Linux 기초
[리눅스 꿀팁] 리눅스에 .crt 인증서 설치하고 컨테이너 런타임 재시작까지 자동화하는 스크립트 (+원격 서버 지원)
mdchung
2025. 4. 8. 15:25
[리눅스 꿀팁] 리눅스에 .crt 인증서 설치하고 도커 재시작까지 자동화하는 스크립트 (+원격 서버 지원)
📌 이 글은 왜 썼나요?
리눅스를 쓰다 보면 .crt 인증서를 설치해야 하는 경우가 종종 있습니다.
예를 들어 사내 프록시나 사설 인증서(CA)를 시스템에 추가해야 하는 상황이죠.
또는 Docker나 Kubernetes에서 HTTPS 통신을 위해 신뢰할 수 있는 인증서를 시스템에 심어줘야 할 때도 있고요.
이럴 때마다 매번 명령어 검색해서 복붙하고, 서버 환경 따라 커맨드 다르게 쓰고... 귀찮고 헷갈립니다.
그래서 한 번에 .crt 인증서 추가하고, 도커/컨테이너 런타임도 자동으로 재시작해주는 스크립트를 만들었습니다.
원격 서버에도 바로 전송+설치 가능하도록 만들었기 때문에 서버 여러 대 관리할 때도 유용합니다.
🛠️ 스크립트 주요 기능
- .crt 인증서 파일 찾기 (현재 디렉토리, /etc)
- 인증서 파일 선택
- 로컬/원격 서버 중 설치할 서버 선택
- 원격일 경우 SSH 접속 (비밀번호 or PEM 키 방식 선택)
- RHEL 계열(OS 자동 감지)에 인증서 복사 + 시스템 인증서 갱신
- Docker / containerd / CRI-O 등 컨테이너 런타임 자동 재시작
- 다음 작업 반복 여부 물어보기
🧑💻 언제 써야 하나요?
- Docker에서 사설 레지스트리 사용 시 인증서 오류가 날 때
(예: x509: certificate signed by unknown authority) - 내부 프록시 서버를 사용해야 할 때 사설 인증서 필요할 경우
- Kubernetes 노드에 동일한 인증서를 여러 서버에 배포해야 할 경우
- 인증서를 자주 바꾸는 테스트 환경에서 자동화가 필요할 때
📦 필요한 패키지
스크립트는 SSH 자동 로그인 및 파일 복사를 위해 sshpass를 사용합니다.
❗ 설치 방법
RHEL / Rocky / CentOS 계열:
# EPEL이 없으면 먼저 추가해줍니다
sudo dnf install -y epel-release
# 그 다음 sshpass 설치
sudo dnf install -y sshpass
📂 전체 스크립트
아래 코드를 install_crt.sh 파일로 저장 후 chmod +x install_crt.sh 하면 실행할 수 있습니다.
#!/bin/bash
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
NC='\033[0m'
process_certificate() {
read -p "Enter the .crt file name (e.g., custom-ca.crt): " cert_name
echo "Searching for '${cert_name}' files..."
current_dir_files=($(find "$(pwd)" -type f -name "${cert_name}" 2>/dev/null))
etc_files=($(find /etc -type f -name "${cert_name}" 2>/dev/null))
files=("${current_dir_files[@]}" "${etc_files[@]}")
if [ ${#files[@]} -eq 0 ]; then
echo -e "${RED}❌ No files matching '${cert_name}' were found.${NC}"
return 1
fi
echo "Found ${#files[@]} file(s):"
for i in "${!files[@]}"; do
echo "$((i+1))) ${files[$i]}"
done
read -p "#? " file_num
if [ "$file_num" -lt 1 ] || [ "$file_num" -gt ${#files[@]} ]; then
echo -e "${RED}❌ Invalid selection.${NC}"
return 1
fi
selected_file="${files[$((file_num-1))]}"
echo -e "${GREEN}✅ Selected: ${selected_file}${NC}"
echo "Choose target server:"
echo "1) Local server (this machine)"
echo "2) Remote server"
read -p "#? " server_choice
if [ "$server_choice" = "1" ]; then
target_server="localhost"
is_local=true
echo -e "${GREEN}✅ Selected: Local server${NC}"
else
is_local=false
read -p "Enter target server IP or hostname: " target_server
read -p "Enter SSH username: " ssh_user
echo "Choose authentication method for ${target_server} (default PEM):"
echo "1) PEM"
echo "2) Password"
read -p "#? " auth_method
ssh_opts="-o StrictHostKeyChecking=no"
if [ "$auth_method" = "2" ]; then
ssh_opts="$ssh_opts -o PreferredAuthentications=password -o PubkeyAuthentication=no"
read -sp "Enter SSH password: " ssh_pass
echo
else
read -p "Enter path to PEM key file: " pem_file
ssh_opts="$ssh_opts -i $pem_file"
fi
echo "Checking OS on ${target_server}..."
if [ "$auth_method" = "2" ]; then
os_info=$(sshpass -p "$ssh_pass" ssh $ssh_opts $ssh_user@$target_server "cat /etc/os-release" 2>/dev/null)
else
os_info=$(ssh $ssh_opts $ssh_user@$target_server "cat /etc/os-release" 2>/dev/null)
fi
if [ $? -ne 0 ]; then
echo -e "${RED}❌ Failed to connect to ${target_server}.${NC}"
return 1
fi
echo -e "${YELLOW}OS Info:${NC}"
echo "$os_info"
fi
if [ "$is_local" = true ]; then
local_cert_path="$selected_file"
else
echo "Transferring ${cert_name} to ${target_server}..."
if [ "$auth_method" = "2" ]; then
sshpass -p "$ssh_pass" scp $ssh_opts "$selected_file" $ssh_user@$target_server:/tmp/$cert_name
else
scp $ssh_opts "$selected_file" $ssh_user@$target_server:/tmp/$cert_name
fi
if [ $? -ne 0 ]; then
echo -e "${RED}❌ Certificate transfer failed.${NC}"
return 1
fi
echo -e "${GREEN}✅ Transferring ${cert_name} to ${target_server}...${NC}"
fi
echo "Updating certificate..."
if [ "$is_local" = true ]; then
if grep -iE '(ID=|ID_LIKE=).*rhel|rocky|centos|fedora' /etc/os-release; then
sudo cp "$local_cert_path" /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust
echo 'Certificate updated in RHEL-based system'
update_status=$?
else
echo 'Unsupported OS'
update_status=1
fi
else
remote_cmd="
if grep -iE '(ID=|ID_LIKE=).*rhel|rocky|centos|fedora' /etc/os-release; then
sudo cp /tmp/$cert_name /etc/pki/ca-trust/source/anchors/ &&
sudo update-ca-trust &&
echo 'Certificate updated in RHEL-based system' &&
exit 0
else
echo 'Unsupported OS';
exit 1
fi"
if [ "$auth_method" = "2" ]; then
update_result=$(sshpass -p "$ssh_pass" ssh $ssh_opts $ssh_user@$target_server "$remote_cmd")
else
update_result=$(ssh $ssh_opts $ssh_user@$target_server "$remote_cmd")
fi
update_status=$?
echo "$update_result"
fi
if [ $update_status -ne 0 ]; then
echo -e "${RED}❌ Certificate update failed.${NC}"
return 1
fi
echo -e "${GREEN}✅ Certificate installed successfully${NC}"
echo "Restarting container runtime..."
restart_block='
if systemctl is-active --quiet docker; then
sudo systemctl restart docker && echo "Docker restarted" && exit 0
elif systemctl is-active --quiet containerd; then
sudo systemctl restart containerd && echo "Containerd restarted" && exit 0
elif systemctl is-active --quiet cri-o || systemctl is-active --quiet crio; then
if systemctl is-active --quiet cri-o; then
sudo systemctl restart cri-o && echo "CRI-O restarted (cri-o)" && exit 0
else
sudo systemctl restart crio && echo "CRI-O restarted (crio)" && exit 0
fi
else
echo "No container runtime found" && exit 1
fi'
if [ "$is_local" = true ]; then
eval "$restart_block"
restart_status=$?
else
if [ "$auth_method" = "2" ]; then
restart_result=$(sshpass -p "$ssh_pass" ssh $ssh_opts $ssh_user@$target_server "$restart_block")
else
restart_result=$(ssh $ssh_opts $ssh_user@$target_server "$restart_block")
fi
restart_status=$?
echo "$restart_result"
fi
if [ $restart_status -ne 0 ]; then
echo -e "${YELLOW}⚠️ No container runtime found or restart failed. Continuing anyway.${NC}"
else
echo -e "${GREEN}✅ Container runtime restarted${NC}"
fi
echo -e "\n${GREEN}모든 작업이 완료되었습니다!${NC}"
if [ "$is_local" = true ]; then
echo -e "${YELLOW}서버: 로컬 서버${NC}"
else
echo -e "${YELLOW}서버: ${target_server}${NC}"
fi
return 0
}
while true; do
process_certificate
echo -n "계속 진행하시겠습니까? (Y/n): "
read answer
if [ "$answer" = "n" ] || [ "$answer" = "N" ]; then
echo "프로그램을 종료합니다."
break
fi
echo -e "\n새로운 작업을 시작합니다.\n"
done
exit 0
✅ 사용 예시
./install_crt.sh
- .crt 파일 이름 입력 → 찾은 파일 중 선택
- 설치할 서버 선택 (로컬 or 원격)
- 원격이면 접속 방식(PW / PEM) 선택 후 접속
- 인증서 복사 및 갱신 → 컨테이너 런타임 재시작
- 다음 작업 계속할지 물어봄