postgresql 13버전 설치

yum update -y

 

cd > [to workspace]

 

wget https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

 

yum install -y pgdg-redhat-repo-latest.noarch.rpm

 

sudo yum install -y postgresql13 postgresql13-server

 

sudo /usr/pgsql-13/bin/postgresql-13-setup initdb

 

sudo systemctl start postgresql-13

 

sudo systemctl enable postgresql-13

 

 

postgresql 계정 설정

sudo -i -u postgres

psql

CREATE USER testuser WITH PASSWORD 'test2020@' ;

ALTER USER testuser WITH SUPERUSER ;

\du

 

database 생성

CREATE DATABASE test OWNER testuser ;

GRANT ALL PRIVILEGES ON DATABASE test TO testuser ;

\l 

 

접속 권한 설정

sudo sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/g" /var/lib/pgsql/13/data/postgresql.conf

echo "host    all             all             0.0.0.0/0               md5" | sudo tee -a /var/lib/pgsql/13/data/pg_hba.conf

 

 

postgresql 설정 적용 재실행

sudo systemctl restart postgresql-13

sudo systemctl status postgresql-13

 

 

Dbeaver 등 tool을 이용 접속 확인

 

sudo yum install epel-release (CentOS)

sudo amazon-linux-extras install epel (Amazon linux2)

 

 

AWS

VPC - Internet gateways, NAT gateways, Route tables, Subnets

VPC Security - Network ACLs

EC2

 

 

1. VPC 생성

name : test-vpc

CIDR : 10.90.0.0/16

 

2. Internet gateway 생성

Internet gateway

name : test-igw

 

Internet gateway vpc connect

vpc 연결 : test-vpc

 

 

3. Private Subnet, Public Subnet 생성

Private Subnet-01

vpc : test-vpc

name : test-pri-sub01

CIDR : 10.90.10.0/24

Availability Zone : ap-northeast-2b

 

Public Subnet-01

vpc : test-vpc

name : test-pub-sub01

CIDR : 10.90.1.0/24

Availability Zone : ap-northeast-2a

 

Public Subnet-02

vpc : test-vpc

name : test-pub-sub02

CIDR : 10.90.3.0/24

Availability Zone : ap-northeast-2b

 

 

4. NAT gateway 생성

NAT gateway

name : test-natGateway

 

subnet

test-pub-sub01

 

Allocate Elastic IP address

할당 받은 IP를 생성한 NAT gateway에 배정

 

 

5. Route table 설정

Private Route table

vpc : test-vpc

name : test-routeTable-pri

explicit subnet association : test-pri-sub01

 

routes

0.0.0.0/0 - NAT gateway

10.90.0.0/16 local

 

 

Public Route table

vpc : test-vpc

name : test-routeTable-pub

explicit subnet association : test-pub-sub01

 

routes

0.0.0.0/0 - Internet gateway

10.90.0.0/16 local

 

6. Network ACLs 설정

Private Network ACL

Inbound Rules:

100 HTTP TCP 80 0.0.0.0/0 DENY
110 HTTPS TCP 443 0.0.0.0/0 DENY
120 SSH TCP 22 0.0.0.0/0 DENY
130 Ephemeral TCP 1024-65535 0.0.0.0/0 ALLOW
140 Custom Rule TCP 80 Subnet Range ALLOW
150 Custom Rule TCP 443 Subnet Range ALLOW
160 Custom Rule TCP 22 Subnet Range ALLOW
* ALL Traffic ALL ALL 0.0.0.0/0 DENY

Outbound Rules:

100 HTTP TCP 80 0.0.0.0/0 ALLOW
110 HTTPS TCP 443 0.0.0.0/0 ALLOW
120 Ephemeral TCP 1024-65535 0.0.0.0/0 ALLOW
* ALL Traffic ALL ALL 0.0.0.0/0 DENY

여기서 "Subnet Range"는 사용 중인 서브넷의 IP 주소 범위를 의미합니다. 여기선 10.90.10.0/24

 

Public Network ACL

Inbound Rules:

100 HTTP TCP 80 0.0.0.0/0 ALLOW
110 HTTPS TCP 443 0.0.0.0/0 ALLOW
120 SSH TCP 22 0.0.0.0/0 ALLOW
130 Ephemeral TCP 1024-65535 0.0.0.0/0 ALLOW
* ALL Traffic ALL ALL 0.0.0.0/0 DENY

Outbound Rules:

100 HTTP TCP 80 0.0.0.0/0 ALLOW
110 HTTPS TCP 443 0.0.0.0/0 ALLOW
120 Ephemeral TCP 1024-65535 0.0.0.0/0 ALLOW
* ALL Traffic ALL ALL 0.0.0.0/0 DENY

 

7. Test EC2 생성 

 

ssm-pub 인스턴스를 public 서브넷에 생성

ssm-pri 인스턴스를 private 서브넷에 생성, Key 생성(ssm-test) 후 배정

 

 

ssm-pub 인스턴스에서 ssm-pri ssh 접속

ssh -i /home/ohsung/ssm-test.pem ec2-user@10.90.10.236

 

private subnet에 있는 ssm-pri 인스턴스에서 NAT gateway를 통해 인터넷 통신 확인

AWS

lambda

cloud Watch - event bridge

IAM

 

Etc

slack

 

 

1. IAM role 생성

AmazonEC2ReadOnlyAccess 정책 배정

 

 

2. lambda function생성

Runtime - Python 3.9

Permissions - 1번에서 만든 role 사용

 

  • code 작성 ( local 환경 )

Lambda 함수에서 `requests` 모듈을 사용하는 경우, 해당 모듈을 포함한 배포 패키지를 만들어야 합니다. Lambda는 기본적으로 `requests` 라이브러리를 포함하지 않으므로, 직접 포함시켜야 합니다.

mkdir lambda_function
cd lambda_function
pip install requests -t .
import boto3
import json
import os
import requests

def lambda_handler(event, context):
    # EC2 클라이언트 생성
    ec2 = boto3.client('ec2')
    
    # 사용 가능한 EBS 볼륨 찾기
    volumes = ec2.describe_volumes(
        Filters=[
            {
                'Name': 'status',
                'Values': ['available']
            }
        ]
    )
    
    available_volumes = volumes['Volumes']
    
    # 사용 가능한 EBS 볼륨이 있는지 확인
    if not available_volumes:
        print("No available volumes found.")
        return
    
    # 사용 가능한 EBS 볼륨 정보 생성
    volume_info = ""
    for volume in available_volumes:
        volume_info += f"Volume ID: {volume['VolumeId']}, Size: {volume['Size']} GiB, Availability Zone: {volume['AvailabilityZone']}\n"
    
    # 사용 가능한 EBS 볼륨 정보 출력
    print("Available volumes:\n", volume_info)
    
    # Slack Webhook URL
    slack_webhook_url = os.environ['SLACK_WEBHOOK_URL']
    
    # Slack으로 메시지 전송
    slack_message = {
        'text': f"Available EBS Volumes:\n{volume_info}"
    }
    
    response = requests.post(slack_webhook_url, data=json.dumps(slack_message), headers={'Content-Type': 'application/json'})
    
    if response.status_code != 200:
        raise ValueError(f"Request to Slack returned an error {response.status_code}, the response is:\n{response.text}")
    
    return {
        'statusCode': 200,
        'body': json.dumps('Slack message sent successfully!')
    }

 

  • .zip으로 압축
zip -r ../lambda_function.zip .

 

  • zip 파일 업로드

 

  • Slack app 생성 ( SLACK_WEBHOOK_URL )
  1. Slack API 페이지에 접속합니다.
  2. "Create a Slack App"을 클릭합니다.
  3. App 이름과 Development Slack Workspace를 선택하고 "Create App"을 클릭합니다.
  4. "Incoming Webhooks"을 활성화합니다.
  5. "Add New Webhook to Workspace"을 클릭하고, Webhook을 보낼 채널을 선택합니다.
  6. Webhook URL을 복사해 둡니다

 

  • lambda 환경 변수에 `SLACK_WEBHOOK_URL` 등록

 

  •  Slack 채널 추가 및 앱 등록 후 lambda code test

 

  • cron 등록

cloud watch -> events -> rules -> create rule -> rule type ( schedule ) -> continue in EventBridge Scheduler

 

cron(0 0 ? * 2 *)

0 0은 00:00 (자정)을 의미하고, ?는 특정한 일자를 지정하지 않음을 의미합니다. * * 2 *은 매주 월요일을 나타냅니다.

 

EC2 인스턴스 1대 이상 준비

https://yes5.tistory.com/29

 

AWS EC2 생성 (ubuntu 프리티어)

EC2 검색 > 인스턴스 인스턴스 시작 클릭 이름 지정 OS 선택 (여기선 ubuntu Server 22.04 LTS ) 인스턴스 유형 t2.micro 키 페어 선택 없다면 새 키 페어 생성 .pem으로 생성 putty 사용자라면 .ppk 네트워크 설

yes5.tistory.com

인스턴스 ID 클릭 > 태그 > 태그 관리

DAY : 정지, 가동 기능을 사용 할 요일 선택

TIME : 가동 할 시간 선택 (범위 밖의 시간은 정지 상태)

AUTOSTOP_ENABLE : true 사용, false 미사용

저장

 

IAM 검색 > 액세스 관리 > 정책

 

정책 생성

 

정책 편집기 > JSON

 

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:StartInstances",
                "ec2:StopInstances"
            ],
            "Resource": "arn:aws:ec2:*:*:instance/*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "ec2:DescribeInstances",
                "ec2:DescribeTags",
                "logs:CreateLogGroup",
                "logs:PutLogEvents",
                "ec2:DescribeInstanceStatus"
            ],
            "Resource": "*"
        }
    ]
}

위 코드 내용 복붙

 

다음

 

정책 이름 : EC2_Auto_Start_Stop

설명 : EC2_Auto_Start_Stop

> 정책 생성

 

IAM > 엑세스 관리 > 역할 > 역할 만들기

 

AWS 서비스

 

사용 사례 > Lambda

 

다음

 

권한정책 > 검색창 EC2_Auto_Start_Stop 입력 > 선택 > 다음

 

역할 이름 : EC2_Auto_Start_Stop_Role > 역할 생성

 

Lambda 검색 >  함수 > 함수 생성

 

함수 이름 : EC2_Auto_Start_Stop_Lambda

런타임 : Python 3.8

 

기본 실행 역할 변경 > 기존 역할 사용 

 

EC2_Auto_Start_Stop_Role 선택 > 함수 생성

 

# -*- coding: utf-8 -*-
import boto3
from datetime import datetime

# 서울 리전
region = 'ap-northeast-2'
# 월 ~ 일요일 
t = ["월", "화", "수", "목", "금", "토", "일"]

def lambda_handler(event, context):
    # 람다 호출된 시점의 시간을 구합니다.
    print("start")
    now_date = t[datetime.today().weekday()]
    now_hour = int(datetime.now().strftime('%H')) + 9
    print(f"now >> date: {now_date}, hour: {now_hour}")

    # ec2 인스턴스의 모든 태그를 조회합니다.
    ec2 = boto3.client('ec2', region_name=region)
    response = ec2.describe_tags(
        Filters=[
            {
                'Name': 'resource-type',
                'Values': ['instance']
            }
        ]
    )
    
    # 값 임시 저장
    enable_instances = []
    day_instances = {}
    time_instances = {}
    
    # AUTO_STOP_ENABLE 태그가 true인 값만 추출합니다
    for tag in response['Tags']:
        if tag['Key'] == "AUTOSTOP_ENABLE" and tag['Value'].lower() == "true":
            enable_instances.append(tag['ResourceId'])
        if tag['Key'] == "DAY":
            day_instances[tag['ResourceId']] = tag['Value']
        if tag['Key'] == "TIME":
            time_instances[tag['ResourceId']] = tag['Value']

    for instance in enable_instances:
        try:
            # 요일이 일치하는지 확인합니다.
            days = day_instances[instance].split(",")            
            is_day = False
            for d in days:
                if now_date == d:
                    is_day = True
            
            # 시간이 일치하는지 확인합니다.
            times = time_instances[instance].split("~")
            is_start_time = False
            is_end_time = False
            if int(times[1].strip()) == now_hour:
                is_end_time = True
            elif int(times[0].strip()) == now_hour:
                is_start_time = True

            if is_day == True and is_end_time == True:
                # 중지 인스턴스 호출
                ec2.stop_instances(InstanceIds=[instance])
            elif is_day == True and is_start_time == True:
                # 시작 인스턴스 호출
                ec2.start_instances(InstanceIds=[instance])
        except Exception as ex:
            print(ex)
    
    print("end")

코드 소스 > 코드 복붙 > Deploy

 

트리거 추가 

 

EventBridge 선택

 

룰 이름 : EC2_Auto_Start_Stop

cron(0 */1 * * ? *) 매시 정각에 람다 호출 

추가

 


설정 끝 테스트 시작

 

먼저 test, auto-start-stop 인스턴스 모두 종료

test 인스턴스의 태그
auto-start-stop 인스턴스의 태그

람다 함수가 실행 되면 test 인스턴스만 실행되어야 한다. ( 현재 시간 14시 )

 

Test 클릭

 

now >> date : 현재요일, hour: 현재시간 표시

 

스크립트 실행 결과 test 인스턴스만 실행된 것 확인

서버에 침해사고가 발생했을 때 last 명령어로 최근 접속에 대한 정보를 알아야 한다.

개발자나 서버 운영자 개인 계정에 전체 권한을 주지 않고 필요한 계정의 권한과 명령어를 alias에 등록해서 사용하게 하면

계정별 접속 정보를 last명령어로 확인 할 수 있다.

 

예시에선 tomcat 계정이 tomcat 디렉터리와 데몬에 대한 권한을 가졌고, testuser는 개발자의 개인 계정이라고 설정한다.

 

testuser 계정에서 명령어를 실행

vi /home/testuser/.bashrc
# .bashrc
alias logview='su - tomcat -c "tail -f /home/tomcat/logs/catalina.out"'

tomcat 계정의 패스워드를 입력하면 tomcat 로그를 확인 할 수 있다.

로그뷰 외에 톰캣 실행, 정지 등 필요한 명령어를 alias에 등록하여 tomcat 계정 사용을 방지하고 개인 계정 사용을 장려한다.

alias

명령어 사용 시 현재 계정에 등록 된 alias 확인 가능

https://yes5.tistory.com/28

 

EC2 - S3 파일 복사

EC2 서버와 S3 버켓은 구축 되어 있다고 가정하고 시작한다. 안 되어 있다면 https://yes5.tistory.com/29 AWS EC2 생성 (ubuntu 프리티어) EC2 검색 > 인스턴스 인스턴스 시작 클릭 이름 지정 OS 선택 (여기선 ubun

yes5.tistory.com

위 게시물에서 EC2 - S3 간 통신을 다뤘습니다.

이제 로그 백업 시스템을 만들어 보겠습니다.

 

 

vi /home/script/wasbck.sh

#!/bin/bash

# Hostname
HOSTNAME='TWAS01'
#HOSTNAME=`hostname -f`

# Date
# Date 함수 기반 포멧 지정
DATEYMDM=$(date +"%Y-%m-%d" -d '1 days ago')
DATEYMD=$(date +"%Y%m%d" -d '1 days ago')
DATEYM=$(date +"%Y%m" -d '1 days ago')
DATED=$(date +"%d" -d '1 days ago')

# Dir
# tomcat, S3 경로
TOMDIR='/etc/tomcat/logs'
WLOGDIR='/etc/tomcat/was_logs'
S3DIR='s3://kimohseong-test/was'

# 1.copy catalina.out log
aws s3 cp ${TOMDIR}/catalina.out-${DATEYMD}.gz ${S3DIR}/${DATEYM}/${DATED}/${HOSTNAME}/catalina.out.${DATEYMDM}.gz

# 2.copy tomcat log
# 2-1.log 압축
tar zcvfP ${WLOGDIR}/catalina.${DATEYMDM}.log.gz ${TOMDIR}/catalina.${DATEYMDM}.log
tar zcvfP ${WLOGDIR}/localhost.${DATEYMDM}.log.gz ${TOMDIR}/localhost.${DATEYMDM}.log
tar zcvfP ${WLOGDIR}/localhost_access_log.${DATEYMDM}.txt.gz ${TOMDIR}/localhost_access_log.${DATEYMDM}.txt

# 2-2 copy to s3
aws s3 cp ${WLOGDIR}/catalina.${DATEYMDM}.log.gz ${S3DIR}/${DATEYM}/${DATED}/${HOSTNAME}/catalina.${DATEYMDM}.log.gz
aws s3 cp ${WLOGDIR}/localhost.${DATEYMDM}.log.gz ${S3DIR}/${DATEYM}/${DATED}/${HOSTNAME}/localhost.${DATEYMDM}.log.gz
aws s3 cp ${WLOGDIR}/localhost_access_log.${DATEYMDM}.txt.gz ${S3DIR}/${DATEYM}/${DATED}/${HOSTNAME}/localhost_access_log.${DATEYMDM}.txt.gz

#Hostname

서버에서 Hostname을 지정했다면 #HOSTNAME=`hostname -f` 부분의 주석을 풀고 사용

 

#Date

위 스크립트에선 파일 전송을 새벽에 할 계획이기 때문에 로그 저장 날짜를 전송 날짜 전일로 지정

전송 날짜로 지정 하신다면 #Date 부분에 -d '1 days ago' 를 제외하시면 됩니다.

 

#Dir

예시는 tomcat 기준의 경로이며 기본 디폴트 경로가 아님. 필요한 로그의 데몬 경로에 맞게 지정 후 사용

S3DIR 경로도 자신의 버켓 주소로 변경

 

#copy

EC2 서버에 7일, bucket에 90일 저장 후 글래시어에 보낼 계획이기 때문에 mv 명령어 대신 cp 사용

이후 crontab에 삭제 명령어 추가

 

 

crontab -e

0 4 * * * /home/script/wasbck.sh
0 5 * * * find /etc/tomcat/logs/ -type f -mtime +7 -delete
0 6 * * * find /etc/tomcat/was_logs/ -type f -mtime +7 -delete

service crond restart

 

 

 

 

 

+ Recent posts