개요
- 접근 제어를 위한 RBAC 인터페이스 검사 및 구성
- LDAP 서비스에 연결하여 중앙 사용자 집합에 대한 액세스 권한 부여
- 데이터베이스에서 기밀을 암호화하도록 Fernet Key 구성
- 중앙 보안관리 시스템에서 보안사항 가져오기
들어가기 전에...
Airflow 웹 인터페이스
1) Airflow 1.x
- Flask-Admin을 기반으로 개발된 기본 인터페이스
- FAB (Flask-AppBuilder)를 기반으로 개발된 RBAC 인터페이스
2) Airflow 2.x
- FAB (Flask-AppBuilder)를 기반으로 개발된 RBAC 인터페이스
1. Airflow 웹 인터페이스 보안
- 보이는 화면은 RBAC 인터페이스의 첫 화면 (암호 인증이 기본적으로 활성화)
1.1 RBAC 인터페이스에 사용자 추가
1.1.1 Command로 User 추가
$ airflow users create \
--role Admin \
--username ethan \
--password topsecret \
--email ethan@company.com \
--firstname kim \
--lastname ethan
- 다음 구문으로 'Admin'이라는 역할을 갖는 사용자가 생성
- 특정 구성 요소에 대해 접근할 수 있는 권한과 역할을 갖음
1.1.2 Airflow에서 User 추가
- Apache의 Docker Image가 기본적으로 ID : airflow / PW : airflow 로 설정되어 있음
1.2 Security
List Users | 사용자 리스트 |
List Roles | 사용자 역할 |
User's Statistics | 사용자 통계 |
Base Permissions | 기본 권한 |
Views/Menus | 뷰/메뉴 |
Permission on Views/Menus | 뷰/메뉴에 대한 권한 |
1.2.1 List Users
- 사용자 목록 확인 가능
- Edit Record를 통해 사용자 정보 변경 가능
1.2.2 List Roles
- Security의 'List Roles'를 확인해 보면, Airflow의 기본 역할 및 해당 권한을 확인할 수 있음
역할명 | 역할의 의도 및 사용 | 기본 권한 |
Admin | 보안 권한 관리 시에만 필요 | 모든 권한 |
Public | 인증되지 않은 사용자 | 권한 없음 |
Viewer | Airflow에서 '보기'만 허용 | DAG에 대한 읽기 액세스 |
User | 보안사항(연결, 변수 등)을 편집할 수 있는 개발자와 편집할 수 없는 개발자를 팀에서 엄격하게 분리하려는 경우 유용 이 역할은 보안사항이 아닌 DAG를 생성할 수 있는 권한 만 부여 |
뷰어와 동일하지만 DAG에 대한 편집 권한(지우기, 트리거, 일시 중지 등)이 존재 |
Op | Airflow DAG 개발에 필요한 모든 권한 | 사용자와 동일하지만 연결, 풀, 변수, XCom 및 구성을 보고 편지할 수 있는 추가 권한 |
ex) Public 역할에 'menu access on Docs' 권한을 추가
1) 'List Roles' 항목으로 이동
- Public Role의 'Edit record'를 선택
2) Permissions 적용
- Permissions에서 'menu access on Docs'를 선택
3) Airflow 페이지 확인
- 다음과 같이 'public role'에 권한을 부여하여 로그인 하지 않아도 문서 메뉴가 표시되는 것을 확인 할 수 있음
2. 미사용 데이터 암호화
- RBAC 인터페이스를 사용하기 위해 사용자 이름과 암호를 DB에 저장하여 사용
- Airflow 여러 구성 요소는 모든 SW는 접근 권한이 없는 게스트가 시스템에 액세스할 수 있는 경로 역할을 하므로 잠재적인 위협이 됨
- Airflow 웹서버와 같은 실질적인 이유로 서비스를 노출해야 하는 경우, 항상 공개적으로 Access 할 수 없도록 해야 함
2.1 Fernet Key
- Airflow의 암호화 설정을 활성화 하여 Airflow Database에 문자열 형태로 저장
- 침입자가 Access 권한을 얻은 후에도 Data를 안전하게 보호 가능
- Airflow는 Fernet Key를 사용해 보안 사항을 암호화 및 복호화할 수 있음
2.2 Fernet Key 생성
from cryptography.fernet import Fernet
fernet_key=Fernet.generate_key()
print(fernet_key.decode())
# YlCImzjge_TeZc7jPJ7Jz2pgOtb4yTssA1pVyqIADWg=
- 이 후, AIRFLOW__CORE__FERNET_KEY 구성 항목을 설정하여 Airflow에 제공
AIRFLOW__CORE__FERNET_KEY=YlCImzjge_TeZc7jPJ7Jz2pgOtb4yTssA1pVyqIADWg=
- Fernet Key를 사용해서 커넥션, 변수, 사용자 비밀번호와 같은 기밀을 암호화 및 복호화 가능
- Fernet Key를 통해 암호화 된 값들은 해독할 수 있으므로 안전하게 유지하는 것이 필수
2.3 Fernet Key 보관 방법
- 일반 텍스트로 저장하지 않기 위해 Bash 명령에서 값을 읽도록 Airflow를 구성
- AIRFLOW__CORE__FERNET_KEY_CMD=cat /path/to/secret 에서 설정
- 이 후 Fernet Key를 가지고 있는 파일을 Airflow 사용자만 읽기 전용으로 설정
3. LDAP 서비스로 연결
- 회사에서는 대부분 사용자 관리를 위한 기존 시스템이 존재
- 새롭게 사용자 집합을 구성 관리하는 것보다, Airflow를 기존의 사용자 관리 시스템에 연결하는 것이 훨씬 편리
디렉터리 서비스
- Azure AD 또는 OpenLDAP와 같은 LDAP 프로토콜을 지원하는 서비스를 사용하는 것
- Airflow가 LDAP 서비스에 연결되면 로그인 시에 백그라운드의 LDAP 서비스에서 사용자 정보를 가져옴
- 사용자는 LDAP를 사용하여 액세스할 수 있는 Directory Service에 저장
- 위 작업을 통해 사용자가 한 번만 생성되면 모든 애플리케이션에 연결
3.1 LDAP의 이해
- LDAP과 Directory Service(Azure AD 또는 OpenLDAP) 관계는 SQL과 RDB 간의 관계와 유사
- LDAP이 Directory Service를 Query 하는 데 사용
LDAP과 RDB의 차이점
LDAP | RDB |
데이터를 따르는 대량의 읽기 작업을 위해 설계 ex) 사용자 계정이 자주 요청되지만, 일반적으로 변경되지 않기 때문에 사용자 계정을 저장하는 데 적합 |
저장하려는 데이터의 트랜잭션 사용을 위해 설계 ex) 거래가 자주 이루어지고, 거래 분석에 다양한 유형의 집계가 포함되기 때문에 거래 시스템을 지원하는 데 적합 |
3.1.1 Directory Service Entity
- Directory Service에서 Entity는 DIT (디렉터리 정보 트리) 라는 계층 구조에 저장
- 각 항목을 Entry라고 하며 Key-Value 쌍으로 저장, DN (Distinguished Nmae)으로 개별적으로 식별
DIT 계층 구조
dc (domain component) | 도메인 구성 요소, 트리를 시작 |
ou (organizational unit) | 조직 단위 약자 |
cn (common name) | 일반 이름 약자 |
데이터를 저장하고 구조화하는 방법에 대한 LDAP 요구 사항이 설정
3.1.2 LDAP 작업 개요
- SQL이 [SELECT, INSERT, UPDATE, DELETE] 와 같은 특정 명령문을 제공하는 것처럼 LDAP은 디렉터리 서비스에 대한 일련의 작업을 제공
LDAP 작업 개요
LDAP 작업 | 설명 |
Abandon | 이전에 요청한 작업을 중단 |
Add | 새 항목을 만듬 |
Bind | 주어진 사용자로 인증 기술적으로 디렉토리 서비스에 대한 첫 번쨰 연결은 익명 이 후 바인드 작업은 지정된 사용자의 ID를 변경하여 디렉토리 서비스에서 특정 작업을 수행할 수 있도록 함 |
Compare | 주어진 항목에 주어진 속성 값이 포함되어 있는지 확인 |
Delete | 항목을 제거 |
Exetended | LDAP 표준에 정의되지 않았지만, 디렉터리 서비스에서 사용할 수 있는 작업을 요청 |
Modify DN | 항목의 DN 변경 |
Modify | 항목의 속성을 편집 |
Search | 주어진 기준과 일치하는 항목을 검색하고 반환 |
Unbind | 디렉터리 서비스에 대한 연결을 닫음 |
ex) LDAP 검색
ldapsearch -b "dc=apacheairflow,dc=com"
ldapsearch -b "dc=apacheairflow,dc=com" "(uid=bsmith)"
1. dc=apacheairflow, dc=com 아래의 모든 항목이 나열
2. dc=apacheairflow, dc=com (uid=bsmith) 아래의 모든 항목이 나열
3.2 LDAP 서비스에서 사용자 가져오기
- LDAP 인증은 FAB를 통해 지원
- web-server_config.py($AIRFLOW_HOME)에서 구성
- FAB는 LDAP 서비스에서 주어진 사용자 이름과 비밀번호를 검색
web-server_config.py에서 LDAP 동기화 구성
from flask_appbuilder.security.manager import AUTH_LDAP
AUTH_TYPE=AUTH_LDAP
AUTH_USER_REGISTRATION=True
AUTH_USER_REGISTRATION_ROLE = "User"
AUTH_LDAP_SERVER="ldap://openldap:389"
AUTH_LDAP_USE_TLS=False
AUTH_LDAP_SEARCH = "dc=apacheairflow,dc=com"
AUTH_LDAP_BIND_USER = "cn=admin,dc=apacheairflow,dc=com"
AUTH_LDAP_BIND_pASSWORD = "admin"
AUTH_LDAP_UID_FIELD = "uid"
3.3 LDAP 사용으로 얻어지는 효과
- LDAP과 연동하여 Airflow에서 사용자를 수동으로 만들고 유지 관리할 필요가 없게 됨
- 모든 사용자는 사용자 정보가 저장되는 유일한 시스템인 LDAP 서비스에 저장
- 모든 AP는 자신을 유지하지 않고도 LDAP 서비스에서 사용자 자격 증명을 확인 가능
4. 웹 서버에 대한 트래픽 암호화
- 침입자는 시스템의 다양한 위치에서 데이터를 얻을 수 있슴
MITM (man-in-the-middle attack) ?
-> 두 시스템 또는 사람이 통신하는 동안 세 번째 사람이 가로채서 메시지를 읽고 이를 전달하는 공격
그럼 Airflow는 전송중인 데이터를 안전하게 보호하려면 어떻게 해야 할까?
4.1 HTTPS 이해
- Airflow 웹 서버와 안전하게 통신하려면 HTTPS를 통해 통신해야 함
HTTP VS. HTTPS
1) HTTP
- HTTP는 웹사이트를 탐색할 때 요청 ID를 확인하기 위한 양쪽에서 어떤 검사도 수행하지 않음
2) HTTPS
- HTTPS는 초기 핸드셰이크에는 원격 측의 유효성을 확인하는 더 많은 단계가 포함
- HTTPS에서 사용되는 암호화는 대칭 암호화와 비대칭 암호화 모두 사용하는 TLS (Transport Layer Security) 전송 계층 보안
대칭암호화 VS. 비대칭암호화
1) 대칭암호화
- 암호화화 복호화 모두 단일 키를 적용
2) 비대칭암호화
- 공개 및 개인의 두 키로 구성
- 비대칭 암호화는 공개 키로 암호화된 데이터는 개인 키로만 해독할 수 있고 개인 키로 암호화된 데이터는 공개 키로만 해독할 수 있슴
결과적으로 HTTPS에서 실행 FLOW
HTTPS 세션이 시작 -> 공개적으로 공유할 수 있는 키가 있는 파일의 인증서를 사용자(브라우저)에게 봔환 -> 브라우저는 임의로 생성된 세션 키를 공개 키로 암호화하여 웹 서버에 반환 -> 개인 키로만 이 메시지를 해독 및 액세스 가능
4.2 HTTPS 인증서 구성
- Airflow는 HTTP를 통해 웹 서버에 접근하거나 내부적 구성 요소 간에 통신이 발생
- Man-in-the-middle 공격을 방지하기 위해 트래픽을 암호화
4.2.1 Airflow HTTPS 적용
엔드 포인트 웹 서버를 보호하는 방법 -> 두 가지 항목이 필요
* 개인 키 (기밀 유지)
* 인증서 (공유하기에 안전함)
자체 서명된 인증서 만들기
openssl req \
-x509 \
-newkey rsa:4096 \
-sha256 \
-nodes \
-days 365 \
-keyout privatekey.pem \
-out certificate.pem \
-extensions san \
-config \
<(echo "[req]";
echo distinguished_name=req;
echo "[san]";
echo subjectAltName=DNS:localhost, IP:127.0.0.1 ) \
-subj "/CN=localhost"
- 비공개 키와 인증서는 모두 Airflow에서 사용할 수 있는 경로에 저장되어야 함
AIRFLOW__WEBSERVER__WEB_SERVER_SSL_CERT=/path/to/certificate.pem
AIRFLOW__WEBSERVER__WEB_SERVER_SSL_KEY=/path/to/privatekey.pem
- 위 상태가 구성이 되면 'https://localhost:8080'을 통해 접근이 가능
Airflow 웹 서버에 HTTPS를 적용하면서 얻을 수 있는 효과..
- 웹 서버간의 트래픽이 암호화, 따라서 공격자가 Data를 가로채도 암호화 되어 읽을 수 없기 때문에 쓸모가 없어짐
- 보안성 강화
5. 시크릿 관리 시스템에서 자격 증명 가져오기
- Airflow에 시크릿 값을 복사, 붙여 넣는 대신 시크릿 스토리지 시스템 중 하나에 연결하는 것이 더 편리하고 안전
- Airflow에서 외부 시크릿 스토리지 시스템에서 시크릿을 가져오는 '시크릿 벡엔드' 기능 도입
- 시크릿 관리 시스템으로는 AWS SSM, GCP Secret Manager, HashiCorp Vault가 지원되고, 이를 통해 기밀을 저장 관리하여 Airflow와 같은 애플리케이션과 필요한 경우에만 공유
'BigData > Airflow' 카테고리의 다른 글
[Airflow] Task 의존성 정의 방법 (0) | 2022.09.14 |
---|---|
[Airflow] Airflow UI (0) | 2022.09.08 |
[Airflow] Airflow Install (0) | 2022.09.07 |
[Airflow] Apache Airflow 란? (0) | 2022.09.05 |