[openssl] RootCA 및 SSL 인증서 만들기 for Linux

#!/bin/bash
###########################################################################
#
# openssl 인증서 생성
#
###########################################################################
CERT_NAME="esvali"
DOMAIN_NAME="esvali.com"
MX_RECORD_NAME="mail.esvali.com"
COMPANY_NAME="eSecuVali Corp."
DEFAULT_DAYS=36500

TMP_CONF_SERVER="server_openssl.conf"
TMP_CONF_ROOTCA="rootca_openssl.conf"

func_write_ca_self_conf() {
  echo "###########################################################################"
  echo "#"
  echo "# openssl.cnf 파일 쓰기"
  echo "#"
  echo "###########################################################################"

  echo "[ req ]" >> ${TMP_CONF_ROOTCA}
  echo "default_bits = 2048" >> ${TMP_CONF_ROOTCA}
  echo "default_md = sha256" >> ${TMP_CONF_ROOTCA}
  echo "default_keyfile = ${CERT_NAME}_private.key" >> ${TMP_CONF_ROOTCA}
  echo "distinguished_name = req_distinguished_name" >> ${TMP_CONF_ROOTCA}
  echo "extensions = v3_ca" >> ${TMP_CONF_ROOTCA}
  echo "req_extensions = v3_ca" >> ${TMP_CONF_ROOTCA}
  echo "" >> ${TMP_CONF_ROOTCA}
  echo "[ v3_ca ]" >> ${TMP_CONF_ROOTCA}
  echo "basicConstraints = critical, CA:TRUE, pathlen:0" >> ${TMP_CONF_ROOTCA}
  echo "subjectKeyIdentifier = hash" >> ${TMP_CONF_ROOTCA}
  echo "##authorityKeyIdentifier = keyid:always, issuer:always" >> ${TMP_CONF_ROOTCA}
  echo "keyUsage = keyCertSign, cRLSign" >> ${TMP_CONF_ROOTCA}
  echo "nsCertType = sslCA, emailCA, objCA" >> ${TMP_CONF_ROOTCA}
  echo "" >> ${TMP_CONF_ROOTCA}
  echo "[req_distinguished_name ]" >> ${TMP_CONF_ROOTCA}
  echo "countryName = KR" >> ${TMP_CONF_ROOTCA}
  echo "countryName_default = KR" >> ${TMP_CONF_ROOTCA}
  echo "countryName_min = 2" >> ${TMP_CONF_ROOTCA}
  echo "countryName_max = 2" >> ${TMP_CONF_ROOTCA}
  echo "" >> ${TMP_CONF_ROOTCA}
  echo "# 회사명 입력" >> ${TMP_CONF_ROOTCA}
  echo "organizationName = ${COMPANY_NAME}" >> ${TMP_CONF_ROOTCA}
  echo "organizationName_default = ${COMPANY_NAME}" >> ${TMP_CONF_ROOTCA}
  echo "" >> ${TMP_CONF_ROOTCA}
  echo "# 부서 입력" >> ${TMP_CONF_ROOTCA}
  echo "organizationalUnitName = ${COMPANY_NAME}" >> ${TMP_CONF_ROOTCA}
  echo "organizationalUnitName_default = ${COMPANY_NAME}" >> ${TMP_CONF_ROOTCA}
  echo "" >> ${TMP_CONF_ROOTCA}
  echo "# SSL 서비스할 domain 명 입력" >> ${TMP_CONF_ROOTCA}
  echo "commonName = ${MX_RECORD_NAME}" >> ${TMP_CONF_ROOTCA}
  echo "commonName_default = ${MX_RECORD_NAME}" >> ${TMP_CONF_ROOTCA}
  echo "commonName_max  = 64" >> ${TMP_CONF_ROOTCA}

  echo "[ req ]" > ${TMP_CONF_SERVER}
  echo "default_bits            = 2048" >> ${TMP_CONF_SERVER}
  echo "default_md              = sha1" >> ${TMP_CONF_SERVER}
  echo "default_keyfile         = ${COMPANY_NAME}-rootca.key" >> ${TMP_CONF_SERVER}
  echo "distinguished_name      = req_distinguished_name" >> ${TMP_CONF_SERVER}
  echo "extensions              = v3_user" >> ${TMP_CONF_SERVER}
  echo "" >> ${TMP_CONF_SERVER}
  echo "[ v3_user ]" >> ${TMP_CONF_SERVER}
  echo "# Extensions to add to a certificate request" >> ${TMP_CONF_SERVER}
  echo "basicConstraints = CA:FALSE" >> ${TMP_CONF_SERVER}
  echo "authorityKeyIdentifier = keyid,issuer" >> ${TMP_CONF_SERVER}
  echo "subjectKeyIdentifier = hash" >> ${TMP_CONF_SERVER}
  echo "keyUsage = nonRepudiation, digitalSignature, keyEncipherment" >> ${TMP_CONF_SERVER}
  echo "## SSL 용 확장키 필드" >> ${TMP_CONF_SERVER}
  echo "extendedKeyUsage = serverAuth,clientAuth" >> ${TMP_CONF_SERVER}
  echo "subjectAltName          = @alt_names" >> ${TMP_CONF_SERVER}
  echo "[ alt_names]" >> ${TMP_CONF_SERVER}
  echo "## Subject AltName의 DNSName field에 SSL Host 의 도메인 이름을 적어준다." >> ${TMP_CONF_SERVER}
  echo "## 멀티 도메인일 경우 *.${COMPANY_NAME}.com 처럼 쓸 수 있다." >> ${TMP_CONF_SERVER}
  echo "DNS.1 = ${MX_RECORD_NAME}" >> ${TMP_CONF_SERVER}
  echo "DNS.2 = *.${DOMAIN_NAME}" >> ${TMP_CONF_SERVER}
  echo "" >> ${TMP_CONF_SERVER}
  echo "[req_distinguished_name ]" >> ${TMP_CONF_SERVER}
  echo "countryName                     = KR" >> ${TMP_CONF_SERVER}
  echo "countryName_default             = KR" >> ${TMP_CONF_SERVER}
  echo "countryName_min                 = 2" >> ${TMP_CONF_SERVER}
  echo "countryName_max                 = 2" >> ${TMP_CONF_SERVER}
  echo "" >> ${TMP_CONF_SERVER}
  echo "# 회사명 입력" >> ${TMP_CONF_SERVER}
  echo "organizationName              = ${COMPANY_NAME}" >> ${TMP_CONF_SERVER}
  echo "organizationName_default      = ${COMPANY_NAME}" >> ${TMP_CONF_SERVER}
  echo "" >> ${TMP_CONF_SERVER}
  echo "# 부서 입력" >> ${TMP_CONF_SERVER}
  echo "organizationalUnitName          = ${COMPANY_NAME}" >> ${TMP_CONF_SERVER}
  echo "organizationalUnitName_default  = ${COMPANY_NAME}" >> ${TMP_CONF_SERVER}
  echo "" >> ${TMP_CONF_SERVER}
  echo "# SSL 서비스할 domain 명 입력" >> ${TMP_CONF_SERVER}
  echo "commonName                      = ${MX_RECORD_NAME}" >> ${TMP_CONF_SERVER}
  echo "commonName_default              = ${MX_RECORD_NAME}" >> ${TMP_CONF_SERVER}
  echo "commonName_max                  = 64" >> ${TMP_CONF_SERVER}
}

func_mk_ourself_trusted_ca() {
  clear
  echo "###########################################################################"
  echo "#"
  echo "# postfix 인증서 만들기"
  echo "#"
  echo "###########################################################################"
  echo ">>> Step 1: Make ourself a trusted CA"
  openssl req -new -x509 -days ${DEFAULT_DAYS} -extensions v3_ca \
-config ${TMP_CONF_ROOTCA} \
-keyout ${CERT_NAME}_postfix_ca.key \
-out ${CERT_NAME}_postfix_ca.crt

  echo ">>> Step 2: 확인"
  openssl x509 -text -in ${CERT_NAME}_postfix_ca.crt
}

func_mk_rootca_cert() {
  clear
  echo "###########################################################################"
  echo "#"
  echo "# rootCA 인증서 만들기"
  echo "#"
  echo "###########################################################################"
  echo ">>> Step 1: [RootCA Cert] Private 키를 만든다."
  openssl genrsa -aes256 -out ${CERT_NAME}_rootca.key 2048

  echo ">>> Step 2: [RootCA Cert] 인증요청서(Certificate Signing Request) 생성"
  openssl req -new -config ${TMP_CONF_ROOTCA} -key ${CERT_NAME}_rootca.key -out ${CERT_NAME}_rootca.csr

  echo ">>> Step 3: [RootCA Cert] 개인키의 비밀번호 제거"
  cp -fv ${CERT_NAME}_rootca.key ${CERT_NAME}_rootca.key.orig
  openssl rsa -in ${CERT_NAME}_rootca.key.orig -out ${CERT_NAME}_rootca.key

  echo ">>> Step 4: [RootCA Cert] 인증서(Certificate) 생성"
  openssl x509 -req -days ${DEFAULT_DAYS} -extensions v3_ca -set_serial 1 \
-extfile ${TMP_CONF_ROOTCA} \
-in ${CERT_NAME}_rootca.csr \
-signkey ${CERT_NAME}_rootca.key \
-out ${CERT_NAME}_rootca.crt


  echo ">>> Step 5: [RootCA Cert] 확인"
  openssl x509 -text -in ${CERT_NAME}_rootca.crt
}

func_mk_server_cert() {
  clear
  echo "###########################################################################"
  echo "#"
  echo "# rootCA를 기준으로 한 Server SSL 인증서 만들기"
  echo "#"
  echo "###########################################################################"
  echo ">>> Step 1: [SSL Cert] Private 키를 만든다."
  openssl genrsa -aes256 -out ${CERT_NAME}_server_private.key 2048

  echo ">>> Step 2: [SSL Cert] 인증요청서(Certificate Signing Request) 생성"
  openssl req -new -config ${TMP_CONF_SERVER} -key ${CERT_NAME}_server_private.key -out ${CERT_NAME}_server.csr

  echo ">>> Step 3: [SSL Cert] 개인키의 비밀번호 제거"
  cp -fv ${CERT_NAME}_server_private.key ${CERT_NAME}_server_private.key.orig
  openssl rsa -in ${CERT_NAME}_server_private.key.orig -out ${CERT_NAME}_server_private.key

  echo ">>> Step 4: [SSL Cert] 인증서(Certificate) 생성"
  openssl x509 -req -set_serial 01 -days ${DEFAULT_DAYS} -extensions v3_user \
-extfile ${TMP_CONF_SERVER} \
-in ${CERT_NAME}_server.csr \
-CA ${CERT_NAME}_rootca.crt \
-CAcreateserial \
-CAkey  ${CERT_NAME}_rootca.key \
-out ${CERT_NAME}_server.crt

  echo ">>> Step 5: [SSL Cert] 확인"
  openssl x509 -text -in ${CERT_NAME}_server.crt
}

func_usage_app() {
  clear
  echo "##### httpd.conf #####"
  echo "SSLCertificateKeyFile \"${CERT_NAME}_server_private.key\""
  echo "SSLCertificateFile \"${CERT_NAME}_server.crt\""
  echo "SSLCACertificateFile \"${CERT_NAME}_rootca.crt\""
  echo
  echo "##### postfix #####"
  echo "smtpd_tls_key_file = ${CERT_NAME}_server_private.key"
  echo "smtpd_tls_cert_file = ${CERT_NAME}_server.crt"
  echo "smtpd_tls_CAfile = ${CERT_NAME}_rootca.crt"
}

rm -f ${CERT_NAME}_*
func_write_ca_self_conf
#func_mk_ourself_trusted_ca
func_mk_rootca_cert
func_mk_server_cert
func_usage_app

rm -f ${TMP_CONF_ROOTCA}
rm -f ${TMP_CONF_SERVER}

###########################################################################
#
# openssl s_client -showcerts -connect mail.esvali.com:25 -starttls smtp -CAfile /etc/esvali/ssl/esvali_rootca.crt
#
# openssl x509 -text -noout -in /etc/esvali/ssl/esvali_server.crt
# openssl x509 -noout -subject -in /etc/esvali/ssl/esvali_server.crt
#
###########################################################################
위로 스크롤