
인증서
ca.crtonly.key only.crt only_key.pem only_crt.pemkey_crt.pem포트 오픈
AWS S3 Bucket
서버 3개
# ubuntu
# ubuntu에서 루트 인증서 신뢰 등록
cp ca.crt /usr/share/ca-certificates/extra
dpkg-reconfigure ca-certificates
# redis 설치
sudo add-apt-repository ppa:redislabs/redis
apt update
apt install -y redis-server
bind 및 requirepass 설정
sudo vi /etc/redis/redis.conf
....
bind 0.0.0.0
...
requirepass 1234
redis 실행
sudo systemctl start redis-server
redis가 설치된 다른서버에서 테스트
redis-cli -h <redis 서버 주소> -p 6379
mwredis.ddim-test-domain.link:6379> ping
(error) NOAUTH Authentication required.
mwredis.ddim-test-domain.link:6379> auth 1234
OK
mwredis.ddim-test-domain.link:6379> ping
PONG
참고 : redis tls 쓰려면 직접 build 해서 설치하거나, 6.0 버전 이상에서 redis.conf 설정해야 하는 듯 함
#바이너리 파일 설치
wget https://github.com/redis/redis/archive/7.0.12.tar.gz
# jemalloc/jemalloc.h error
cd deps
make hiredis jemalloc linenoise lua
make distclean
# gcc 에러
apt install gcc
#make test 에서 you need tlc 8.5 or newer
apt install tcl
# openssl/ssl.h: No such file or directory
sudo apt-get -y install libssl-dev
# /deps/hdr_histogram/libhdrhistogram.a : no such file or directory
make distclean
make BUILD_TLS=yes
redis.conf 수정vi redis.conf
bind 0.0.0.0
...
requirepass <비밀번호>
...
#port 6379
...
port 0
tls-port 6379
...
tls-cert-file <crt 파일 경로>
tls-key-file <key 파일 경로>
...
tls-client-cert-file <클라이언트 crt파일 경로>
tls-client-key-file <클라이언트 key파일 경로>
...
tls-ca-cert-file <ca인증서 경로>
tls-client-cert-file , tls-client-key-file 는 tls-cert-file, tls-key-file 과 동일하게 설정
# redis 서버 실행
sudo ./src/redis-server redis.conf
# 외부 tls 접속
/*
redis-cli -h 77.88.130.51 -a <requirepass> --tls --cert <서버 crt> --key <서버 key> --cacert <루트 인증서 crt>
77.88.130.51:6379> ping
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
// requirepass 를 직접 쓰면 위험하다는 문구
PONG
*/
redis-cli -h redis.ddim-test-domain.link -p 6379 --tls --cert only.crt --key only.key --cacert ca.crt
redis.ddim-test-domain.link:6379> ping
(error) NOAUTH Authentication required.
redis.ddim-test-domain.link:6379> auth 1234
OK
redis.ddim-test-domain.link:6379> ping
PONG
11 버전 이상 필요
# centos 7 인증서 OS 신뢰 등록
sudo cp ca.crt /etc/pki/ca-trust/source/anchors
# postgresql 설치
sudo yum install -y * # 14 버전 rpm 설치 함
/*
postgresql14-14.8-1PGDG.rhel7.x86_64.rpm
postgresql14-contrib-14.8-1PGDG.rhel7.x86_64.rpm
postgresql14-libs-14.8-1PGDG.rhel7.x86_64.rpm
postgresql14-server-14.8-1PGDG.rhel7.x86_64.rpm
*/
# 실행
cd /usr/pgsql-14/bin
postgresql-14-setup initdb
# 서비스파일 경로
/usr/lib/systemd/system/postgresql-14.service
# config 파일 경로
PGDATA = /var/lib/pgsql/14/data/
/var/lib/pgsql/14/data/postgresql.conf
listen_addresses = '*'
port = 5432
...
ssl = on
ssl_ca_file = '/var/lib/pgsql/14/data/ca.crt' # 루트 인증서 경로
ssl_cert_file = '/var/lib/pgsql/14/data/only.crt' # 도메인 인증서
ssl_key_file = '/var/lib/pgsql/14/data/only.key' # 도메인 키
ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers
ssl_prefer_server_ciphers = on
/var/lib/pgsql/14/data/pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all peer
# IPv4 local connections:
local all all 0.0.0.0/0 scram-sha-256
# IPv6 local connections:
host all all ::1/128 scram-sha-256
# Allow replication connections from localhost, by a user with the
# replication privilege.
local replication all peer
host replication all 127.0.0.1/32 scram-sha-256
host replication all ::1/128 scram-sha-256
hostssl all all 0.0.0.0/0 scram-sha-256
참고
method가 peer 는 os 사용자 이름 = psql 유저 이름 이어야 로그인 가능
scram-sha-256 은 패스워드 로그인
sudo systemctl restart postgresql-14.service
FATAL: could not load private key file "/etc/postgresql/14/main/only.key": Permission denied 에러 발생시chown postgres only.key
chmod g-r only.key
# 내부 접속
sudo su - postgres
psql
# postgres 유저의 패스워드 변경
alter user postgres with password '<설정 할 패스워드>';
# schema 생성
CREATE SCHEMA rails;
CREATE SCHEMA vault;
CREATE SCHEMA registry;
# 외부 접속
psql -h <postgresql 주소> -U postgres -p 5432
# 이게 뜨면 성공
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
postgres=
→ 반드시!!! 클라이언트 인증서의 CN = postgresql 유저명 이어야 외부접속이 가능하다.
1) pg_hba.conf수정
#pg_hba.conf 수정
# 암호인증과 클라이언트 인증서를 함께
hostssl all all 0.0.0.0/0 scram-sha-256 clientcert=verify-full
# 클라이언트 인증서만
hostssl all all 0.0.0.0/0 cert clientcert=verify-full
클라이언트 인증서 만들기
psql_client.key 생성
openssl genrsa -out psql_client.key 2048
psql_client.csr 생성
openssl req -new -key psql_client.key -out psql_client.csr -config only.conf
-----
Country Name (2 letter code) [KR]:KR
Organization Name (eg, company) [lesstif Inc.]:
Organizational Unit Name (eg, section) [lesstif SSL Project]:
Common Name (eg, your name or your servers hostname) [lesstif.com]:postgres
psql_client.crt 생성
openssl x509 -req -days 365 -extensions v3_user
-in psql_client.csr
-CA ca.crt
-CAcreateserial -CAkey root.key
-out psql_client.crt -extfile only.conf
확인
openssl x509 -text -in psql_client.crt
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
99:1f:61:68:86:c6:21:3f
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = KR, O = lesstif Inc., CN = ddim
Validity
Not Before: Aug 8 02:25:53 2023 GMT
Not After : Aug 7 02:25:53 2024 GMT
Subject: C = KR, O = lesstif Inc., OU = lesstif SSL Project, CN = postgres
외부 접속 연결 테스트
psql "host=psql.ddim-test-domain.link port=5432 user=postgres dbname=postgres sslmode=verify-full sslcert=psql_client.crt sslkey=psql_client.key sslrootcert=ca.crt"
psql (15.3 (Ubuntu 15.3-1.pgdg20.04+1), server 14.8)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, compression: off)
tail -f ./log/postgresql-Tue.log
# 클라이언트 인증서 CN과 db유저명이 같지 않을 경우 나오는 로그
2023-08-08 10:46:54.031 KST [2971] 로그: 제공된 사용자 이름(postgres) 및 인증된 사용자 이름(*.ddim-test-domain.link)이 일치하지 않음
2023-08-08 10:46:54.031 KST [2971] 로그: "postgres" 사용자를 위한 인증서 유효성 검사를 실패 함: CN 같지 않음
2023-08-08 10:46:54.031 KST [2971] 치명적오류: 사용자 "postgres"의 password 인증을 실패했습니다
# centos 7 인증서 OS 신뢰 등록
sudo cp ca.crt /etc/pki/ca-trust/source/anchors
sudo yum install haproxy
centos 7 이면 필수
setenforce 0
# 확인
getenforce
permissive
only_key 와 only_crt를 합친 key_crt.pem파일 준비
sudo vi /etc/haproxy/haproxy.cfg
frontend test
bind *:443 ssl crt /etc/haproxy/key_crt.pem
reqadd X-Forward-Proto:\https
default_backend tfe
backend tfe
balance roundrobin
server tfe1 <tfe 1 주소>:443 check ssl verify none
server tfe2 <tfe 2 주소>:443 check ssl verify none
sudo systemctl restart haproxy
active_active TFE에 접속하면 바로 로그인 페이지가 나오며 admin 계정을 만들지 못한다.
따라서, TFE active_active 설치 하기 전에 외부 Postgresql과 연결되는 External Service TFE를 일회성으로 설치하여 admin 계정을 만들어야 한다.
replicated.tar.gz 혹은 latest.tar.gz) --> 다운로드 링크 루트 인증서 OS에 신뢰 등록
sudo cp ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust
/opt/tfe-installer 디렉토리에서 replicated.tar.gz , terraform.airgap 파일 두고 압축해제
sudo mkdir /opt/tfe-installer
sudo mv replicted.tar.gz terraform.airgap /opt/tfe-installer
sudo tar xzf replicated.tar.gz
docker 설치 후 시작, 확인
sudo systemctl start docker
sudo docker ps
tfe 설치
/opt/tfe-installer
sudo ./install.sh airgap
The installer was unable to automatically detect the private IP address of this machine.
Please choose one of the following network interfaces:
[0] eth0 172.31.60.56
[1] docker0 172.17.0.1
Enter desired number (0-1): 0
....
To continue the installation, visit the following URL in your browser:
http://<this_server_address>:8800
<tfe 설치한 인스턴스 ip>:8800 에 접속해서 설치 진행
Hostname : external tfe 서버주소 입력
인증서 : 서버내에 only_key.pem , only_crt.pem 경로 입력

라이센스 rli 파일 업로드
airgap 패키지 : 서버 내 terraform.airgap 파일 경로 입력
관리자 콘솔 settings 설정


ca.crt 입력
콘솔 확인 및 replicatedctl app status 확인

replicatedctl app status
[
{
"AppID": "2c10da2f9c1f416150a9c89cb0ae34b7",
"Sequence": 692,
"PatchSequence": 0,
"State": "stopped",
"DesiredState": "started",
"Error": "",
"IsCancellable": true,
"IsTransitioning": true,
"LastModifiedAt": "2023-07-26T06:55:28.741570295Z"
}
]
state가 started , IsTransitioning 가 false면 완료
ptfe-settings.json 파일 추출 후 로컬에 저장
replicaetdctl app-config export > ptfe-settings.json
ptfe-settings.json파일 양식{ "aws_access_key_id": {}, "aws_instance_profile": {}, "aws_secret_access_key": {}, "azure_account_key": {}, "azure_account_name": {}, "azure_client_id": {}, "azure_container": {}, "azure_endpoint": {}, "azure_use_msi": {}, "backup_token": {}, "ca_certs": {}, "capacity_concurrency": { "value": "10" }, "capacity_cpus": {}, "capacity_memory": { "value": "512" }, "custom_image_tag": { "value": "hashicorp/build-worker:now" }, "disk_path": { "value": "/opt/terraform-enterprise" }, "enable_active_active": {}, "enc_password": { "value": "CHANGEME" }, "extern_vault_addr": {}, "extern_vault_enable": {}, "extern_vault_namespace": {}, "extern_vault_path": {}, "extern_vault_propagate": {}, "extern_vault_role_id": {}, "extern_vault_secret_id": {}, "extern_vault_token_renew": {}, "extra_no_proxy": {}, "force_tls": {}, "gcs_bucket": {}, "gcs_credentials": {}, "gcs_project": {}, "hairpin_addressing": {}, "hostname": { "value": "terraform.example.org" }, "iact_subnet_list": {}, "iact_subnet_time_limit": {}, "log_forwarding_config": {}, "log_forwarding_enabled": {}, "metrics_endpoint_enabled": {}, "metrics_endpoint_port_http": {}, "metrics_endpoint_port_https": {}, "pg_dbname": {}, "pg_extra_params": {}, "pg_netloc": {}, "pg_password": {}, "pg_user": {}, "placement": {}, "production_type": { "value": "disk" }, "redis_host": {}, "redis_pass": {}, "redis_port": {}, "redis_use_password_auth": {}, "redis_use_tls": {}, "restrict_worker_metadata_access": {}, "s3_bucket": {}, "s3_endpoint": {}, "s3_region": {}, "s3_sse": {}, "s3_sse_kms_key_id": {}, "tbw_image": { "value": "default_image" }, "tls_ciphers": {}, "tls_vers": { "value": "tls_1_2_tls_1_3" } }
ptfe-settings.json (파일명 임의 설정 가능)replicated.conf{
"DaemonAuthenticationType": "password",
"DaemonAuthenticationPassword": "<패스워드 입력>",
"TlsBootstrapType": "server-path",
"TlsBootstrapHostname": "<haproxy 도메인 주소>",
"TlsBootstrapCert": "<only_crt.pem 파일 경로>",
"TlsBootstrapKey": "<only_key.pem 파일 경로>",
"BypassPreflightChecks": true,
"ImportSettingsFrom": "<ptfe-settings.json 파일 경로>",
"LicenseFileLocation": "<라이센스 rli 파일 경로>",
"LicenseBootstrapAirgapPackagePath": "<airgap 패키지 경로>"
}
예시
{ "DaemonAuthenticationType": "password", "DaemonAuthenticationPassword": "ddim", "TlsBootstrapType": "server-path", "TlsBootstrapHostname": "test.ddimtech.com", "TlsBootstrapCert": "/home/centos/all_in/only_crt.pem", "TlsBootstrapKey": "/home/centos/all_in/only_key.pem", "BypassPreflightChecks": true, "ImportSettingsFrom": "/etc/ptfe-settings.json", "LicenseFileLocation": "/home/centos/DDim_License.rli", "LicenseBootstrapAirgapPackagePath": "/opt/tfe-installer/terraform.airgap" }
replicated.conf 는 반드시 /etc 경로에 있어야 함
LicenseBootstrapAirgapPackagePath : airgap 설치 시 필요한 설정aws 키 입력
"aws_access_key_id": {
"value": "<access key 입력>"
},
"aws_instance_profile": {
"value": "0"
},
"aws_secret_access_key": {
"value": "<secret access key 입력>"
},
redis 정보 입력
"redis_host": {
"value": "<redis 도메인 주소>"
},
"redis_pass": {
"value": "<redis.conf의 requirepass 입력>"
},
"redis_port": {
"value": "6379"
},
"redis_use_password_auth": {
"value": "1"
},
active_active 활성화
"enable_active_active": {
"value": "1"
},
hostname 수정
"hostname": {
"value": "<haproxy 도메인 주소 입력>"
}
최종 ptfe-settings.json 파일 형태
{
"aws_access_key_id": {
"value": "<aws_access_key>"
},
"aws_instance_profile": {
"value": "0"
},
"aws_secret_access_key": {
"value": "<aws_secret_access_key>"
},
"azure_account_key": {},
"azure_account_name": {},
"azure_client_id": {},
"azure_container": {},
"azure_endpoint": {},
"azure_use_msi": {
"value": "0"
},
"backup_token": {
"value": "3e69c0572c1eddf7f232cf60f6b8634194bf40d09aa9535c78430e64df407ec4"
},
"ca_certs": {
"value": "<ca.crt 내용 - \n으로 구분되어 있음>"
},
"capacity_concurrency": {
"value": "10"
},
"capacity_cpus": {
"value": "0"
},
"capacity_memory": {
"value": "512"
},
"custom_agent_image_tag": {},
"custom_image_tag": {
"value": "hashicorp/build-worker:now"
},
"disk_path": {},
"enable_active_active": {
"value": "1"
},
"enc_password": {
"value": "<replicated.conf - DaemonAuthenticationPassword 와 같은 패스워드>"
},
"extern_vault_addr": {},
"extern_vault_enable": {
"value": "0"
},
"extern_vault_namespace": {},
"extern_vault_path": {},
"extern_vault_propagate": {},
"extern_vault_role_id": {},
"extern_vault_secret_id": {},
"extern_vault_token_renew": {},
"extra_no_proxy": {},
"force_tls": {
"value": "0"
},
"gcs_bucket": {},
"gcs_credentials": {},
"gcs_project": {},
"hairpin_addressing": {
"value": "0"
},
"hostname": {
"value": "<haproxy 도메인 주소>"
},
"iact_subnet_list": {},
"iact_subnet_time_limit": {
"value": "60"
},
"log_forwarding_config": {},
"log_forwarding_enabled": {
"value": "0"
},
"metrics_endpoint_enabled": {
"value": "0"
},
"metrics_endpoint_port_http": {},
"metrics_endpoint_port_https": {},
"pg_dbname": {
"value": "<postgresql db 명>"
},
"pg_extra_params": {
"value": "sslmode=require"
},
"pg_netloc": {
"value": "<postgresql 도메인 주소:5432>"
},
"pg_password": {
"value": "<유저 패스워드>"
},
"pg_user": {
"value": "<유저명>"
},
"placement": {
"value": "placement_s3"
},
"production_type": {
"value": "external"
},
"redis_host": {
"value": "<redis 도메인 주소>"
},
"redis_pass": {
"value": "<redis requirepass>"
},
"redis_port": {
"value": "6379"
},
"redis_use_password_auth": {
"value": "1"
},
"redis_use_tls": {},
"restrict_worker_metadata_access": {
"value": "0"
},
"run_pipeline_mode": {
"value": "agent"
},
"s3_bucket": {
"value": "<aws_s3 bucket 이름>"
},
"s3_endpoint": {},
"s3_region": {
"value": "<s3 region>"
},
"s3_sse": {},
"s3_sse_kms_key_id": {},
"tbw_image": {
"value": "default_image"
},
"tls_ciphers": {},
"tls_vers": {
"value": "tls_1_2_tls_1_3"
}
}
'4-1. External services TFE 설치' 와 같이 각 노드에 ./install.sh airgap 하기 전 필요 세팅 하기
1) 루트 인증서 OS 신뢰 등록
2) 원하는 경로(/opt/tfe-installer)에 relicated.tar.gz 압축 해제 및 terraform.airgap 파일 두기
3) docker 설치 및 시작
cd /opt/tfe-installer
sudo ./install.sh disable-replicated-ui airgap
disable-replicated-ui 를 하면 8800포트의 관리자 설정페이지가 disable 됨
sudo ./install.sh airgap로 설치해 8800포트로 접속해도 되지만, active_active는 8800포트의 관리자 콘솔 세팅이 제대로 먹히지 않고ptfe-settings.json에서 미리 설정한 세팅 값이 꼬일 수 있으므로 8800포트를 닫고 disable-replicated-ui 추천
확인
라이센스 관련 에러
replicatedctl app status
ERROR : license not upload. please command license-load ~
기다리면 알아서 컨테이너가 올라오면서 라이센스가 업로드 된다. 10분 이상 계속되면, /etc/replicated.conf 에서 LicenseFileLocation 라이센스 경로가 잘못되어 있을 가능성 높음
설치 중
replicatedctl app status
[
{
"AppID": "2c10da2f9c1f416150a9c89cb0ae34b7",
"Sequence": 692,
"PatchSequence": 0,
"State": "stopped",
"DesiredState": "started",
"Error": "",
"IsCancellable": true,
"IsTransitioning": true,
"LastModifiedAt": "2023-07-26T06:55:28.741570295Z"
}
]
설치완료
replicatedctl app status
[
{
"AppID": "2c10da2f9c1f416150a9c89cb0ae34b7",
"Sequence": 692,
"PatchSequence": 0,
"State": "started",
"DesiredState": "started",
"Error": "",
"IsCancellable": false,
"IsTransitioning": false,
"LastModifiedAt": "2023-07-26T06:55:28.741570295Z"
}
]
State가 started, IsTransitioning이 false면 설치 완료
감사합니다. 도움이 많이 되었습니다!