시놀로지 도커 설정
Kim135797531 (토론 | 기여)님의 2020년 2월 27일 (목) 08:46 판
외부 노출 서버 (시놀로지 VMM)
- alpine-virt-3.11.3
역할
- 현재 IPv6 Cloudflare에 보고(갱신)
- 웹 프록시
마운트 설정
- alpine에 nfsmount 설치
- apk add nfsmount
- /etc/fstab에 다음 내용 추가
- 맨 뒤의 _netdev와 0 0을 꼭 추가해야 한다
내부서버IP:/volume1/시놀로지폴더 /마운트경로 nfs nfsvers=3,rsize=524288,wsize=524288,ro,auto,nolock,_netdev 0 0
- 맨 뒤의 _netdev와 0 0을 꼭 추가해야 한다
Cloudflare 연동 IP 등록
- 일본 특성상 IPv4 포트가 매우 제한적으로 열려 있고, 10000번대 밑으로는 아예 열리지도 않음
- IPv6는 이런 제한이 없음. 공유기가 각각의 머신에 뿌려주는 IP는 DHCP라기보다는 일본 인터넷에 직접 연결된 공인 IP.
- IPv6는 설계시부터 모든 기기가 고유의 공인 IP를 갖는 형태로 설계됨. 다만 그 특성상 보안에 취약하므로, 영구 IPv6 주소와 별개로 임시 IPv6가 부여되어, 수시로 주소가 바뀜.
- 주소 바뀜을 체크하여, Cloudflare DNS에 등록해 주는 역할 (v6 레코드인 AAAA를 업데이트 함)
- 다음 파일을 alpine 서버의 /etc/init.d에 저장. (파일 이름 cloudflare-alpine.service)실제 업데이트를 수행하는 Python 파일을 위의 서비스 스크립트에 지정된 위치로 잘 저장
#!/sbin/openrc-run # $apk add python3 # $apk add py3-requests # Copy this file into /etc/init.d/ # Test by $rc-service cloudflare-alpine.service start # $rc-update add cloudflare-alpine.service # $rc-service cloudflare-alpine.service restart # $rc-update -u description="Update Cloudflare DNS" command="/usr/bin/python3 /root/cloudflare-alpine.py" pidfile="/var/run/cloudflare/cloudflare.pid" command_background="yes" depend() { need net need nfsmount need sshd after iptables } start_pre() { ebegin "Starting cloudflare" mkdir -p /var/run/cloudflare || return 1 }
#!/usr/bin/env python # -*- coding: utf-8 -*- import os import requests import json from time import sleep CLOUDFLARE_KEY = 'XXX' CLOUDFLARE_ZONE_ID = 'XXX' CLOUDFLARE_DNS_TOKEN = 'XXX' CLOUDFLARE_HEADER = { 'Authorization': 'Bearer {}'.format(CLOUDFLARE_DNS_TOKEN), 'Content-Type': 'application/json' } DNS_GET_URL = 'https://api.cloudflare.com/client/v4/zones/{}/dns_records'.format(CLOUDFLARE_ZONE_ID) device = 'eth0' addr_file = '/tmp/cloudflare.addr6' def check(): addr = '' try: with open(addr_file, 'r') as f: addr = f.read() except: pass get_addr_cmd = "ip -6 addr list scope global $device | " \ "grep -v ' fd' | " \ "grep -v 'deprecated' | " \ "grep -v 'mngtmpaddr' | " \ "head -n 2 | " \ "tail -n 1" new_addr = os.popen(get_addr_cmd).read() new_addr = new_addr.split()[1] new_addr = new_addr.split('/')[0] if addr == new_addr: print('same ip {}'.format(new_addr)) else: r = requests.get(DNS_GET_URL, headers=CLOUDFLARE_HEADER) j = json.loads(r.text) for item in j['result']: dns_put_url = DNS_GET_URL + '/' + item['id'] new_data = dict( type=item['type'], name=item['name'], content=new_addr, ) if item['type'] == 'AAAA': new_data['proxied'] = True requests.put(dns_put_url, data=json.dumps(new_data), headers=CLOUDFLARE_HEADER) elif item['type'] == 'TXT': new_data['content'] = 'v=spf1 {} ~all'.format(new_addr) requests.put(dns_put_url, data=json.dumps(new_data), headers=CLOUDFLARE_HEADER) with open(addr_file, 'w') as f: f.write(new_addr) f.close() print('updated ip {}'.format(new_addr)) while True: check() sleep(60)
- 그 후 서비스 등록
rc-update add cloudflare-alpine.service rc-service cloudflare-alpine.service restart rc-update -u
Nginx 웹 프록시
- Cloudflare로부터 오는 HTTPS 요청을 처리하여, 내부 서버에 전달
- 처음 도입 목적은 Cloudflare의 IPv6 over IPv4 기능을 이용하기 위함
- 생각해보니 외부/내부를 분리하여 보안성도 높아지고, 도커를 이용한 로드밸런서 구현 및 포트 번호 추상화가 가능해져 채택
- /etc/nginx/conf.d는 시놀로지에 config를 등록해 놓고 폴더째로 마운트
- wiki-proxy.conf 예시
- proxy_set_header를 설정해야 내부 서버에서 보이는 접속 요청 IP가 실제 사용자의 IP로 제대로 뜬다
- 내부 서버사이의 통신은 http로 하여 속도 향상 (방화벽 설정은 따로)
server { listen 80; listen [::]:80; server_name wiki.dong-min.kim; location / { return 301 https://$server_name$request_uri; } } server { listen 443 ssl; listen [::]:443 ssl; ssl_certificate pem파일; ssl_certificate_key key파일; server_name wiki.dong-min.kim; server_tokens off; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $server_name; proxy_set_header Client-IP $remote_addr; proxy_pass http://내부 서버 주소:포트; } }
웹 데몬
Nginx (도커)
역할
- HTTP 요청을 받아서
- 직접 처리(static)하거나
- PHP 인터프리터로 보내거나
- 다른 웹 데몬(Node.js, Python, ...)으로 다시 proxy한다
레포지토리
- https://hub.docker.com/_/nginx
- 1.17.8-alpine
컨테이너 설정
- 포트 설정
- (외부 노출 서버 Nginx Proxy 포트 설정):(그대로)
- 볼륨 설정
- htpasswd -> (비공개)/htpasswd
- passwd -> /etc/passwd
- www -> (비공개)/www/
- nginx/conf.d/ -> /etc/nginx/conf.d/
- nginx/nginx.conf -> /etc/nginx/nginx.conf
- 환경 변수
- (기본값)
인터프리터
PHP (도커)
역할
- PHP 데몬
- FPM(FastCGI Process Manager) 사용하여 동적 워커 생성
레포지토리
- 공식 레포지토리의 7.2.9-fpm-alpine 기반
- 추가로 PHP 확장 기능을 설치하기 위해 Dockerfile 작성
- gd, mysqli
- 이용한 라이브러리
- Dockerfile
- 도커 레포지토리
컨테이너 설정
- 포트 설정
- (비공개):9000
- 참고로 www.conf에서 다른 포트로 설정해도 php-fpm.d/zz-docker.conf에서 무조건 기본값으로 바꿈
- 볼륨 설정
- php.ini -> /usr/local/etc/php/php.ini
- www.conf -> /usr/local/etc/php-fpm.d/www.conf
- www.conf -> /usr/local/etc/php-fpm.d/www.conf.default
- www -> (비공개)/www/
- 환경 변수
- (기본값)
php.ini 설정
- max_execution_time = 30
- max_input_time = 60
- memory_limit = 512M
- post_max_size = 10240M
- upload_max_filesize = 10240M
- default_socket_timeout = 30
- extension gd2, mysqli 활성화
www.conf 설정
- 여기 설정은 주로 미디어위키의 VisualEditor 확장 기능 + Math 수식 입력기를 사용할 때 Restbase 서버에 동시에 많은 요청을 보내는 것을 처리하기 위해 필요함
- pm.max_children = 16
- pm.start_servers = 16
- pm.min_spare_servers = 16
- pm.max_spare_servers = 16
- pm.process_idle_timeout = 30s
데이터베이스
MySQL (도커)
역할
- 워드프레스, 미디어위키에 사용하기 위한 범용 데이터베이스
레포지토리
컨테이너 설정
- 포트 설정
- (외부 노출 서버 Nginx Proxy 포트 설정 시작 번호-2):(그대로)
- 볼륨 설정
- MySQL 실제 DB 파일 폴더 -> /var/lib/mysql/
- mysql.cnf -> /etc/mysql/conf.d/mysql.cnf
- 환경 변수
- (기본값)
Cassandra (도커)
역할
- 미디어위키의 API 백엔드 Restbase에서 사용하기 위한 고성능 데이터베이스
레포지토리
컨테이너 설정
- 포트 설정
- (비공개):9042
- 볼륨 설정
- Cassandra 실제 DB 파일 폴더 -> /var/lib/cassandra/
- Cassandra 설정 폴더 -> /etc/cassandra/
- 환경 변수
- CASSANDRA_BROADCAST_ADDRESS = (호스트 주소)
cassandra-env.sh 설정
- https://www.mediawiki.org/wiki/Parsoid/Setup/RESTBase 참고
- MAX_HEAP_SIZE="128M"
- HEAP_NEWSIZE="20M"
cassandra.yaml 설정
- https://www.mediawiki.org/wiki/Parsoid/Setup/RESTBase 참고
- key_cache_size_in_mb: 0
- concurrent_reads: 2
- concurrent_writes: 2
- rpc_server_type: hsha
- rpc_min_threads: 1
- rpc_max_threads: 1
- concurrent_compactors: 1
- compaction_throughput_mb_per_sec: 0
응용 프로그램(애플리케이션)
워드프레스 (파일)
역할
- 개인 포트폴리오
- https://dong-min.kim
wp-컨피그.php
- FTPS 설정 (SFTP가 아니다)
- 프록시된 요청을 처리하기 위한 추가 설정
- $_SERVER['HTTPS']='on'; 구절만 있으면 된다
- 나머지는 프록시 서버 측의 설정이 잘못된 상태일 때 필요했었다
define('FTP_HOST', '내부 서버 주소:내부 포트 번호'); define('FTP_USER', 'wp-ftps'); define('FTP_PASS', ''); define('FTP_SSL', true); define('FTP_BASE', '(비공개)/wordpress/'); define('FTP_CONTENT_DIR', '(비공개)/wp-content/'); define('FTP_PLUGIN_DIR ', '(비공개)/wp-content/plugins/'); if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') $_SERVER['HTTPS']='on'; // define('RELOCATE', true); // define('WP_HOME', 'https://dong-min.kim'); // define('WP_SITEURL', 'https://dong-min.kim'); /* if ( ! empty( $_SERVER['HTTP_X_FORWARDED_HOST'] ) ) { $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST']; } */
미디어위키 (파일)
역할
확장 기능
- VisualEditor, Math, SyntaxHighlight
LocalSettings.php
<?php
// ... (생략)
$wgArticlePath = "/view/$1";
$wgUsePathInfo = true;
$wgScriptExtension = ".php";
# $wgUploadPath = "";
$wgMathValidModes[] = 'mathml';
$wgDefaultUserOptions['math'] = 'mathml';
$wgMathFullRestbaseURL = 'https://wiki-restbase.dong-min.kim/wiki.dong-min.kim/';
$wgMathMathMLUrl = 'https://wiki-mathoid.dong-min.kim';
$wgDefaultUserOptions['visualeditor-enable'] = 1;
$wgHiddenPrefs[] = 'visualeditor-enable';
$wgVirtualRestConfig['modules']['parsoid'] = array(
'url' => 'http://wiki-parsoid.dong-min.kim',
'domain' => 'wiki.dong-min.kim',
);
$wgVisualEditorRestbaseURL = 'https://wiki-restbase.dong-min.kim/wiki.dong-min.kim/v1/page/html/';
$wgVisualEditorFullRestbaseURL = 'https://wiki-restbase.dong-min.kim/wiki.dong-min.kim/';
?>
미디어위키 Restbase (도커)
- 이 Restbase를 비롯하여 아래의 Parsoid, Mathoid는 미디어위키에서 Visual Editor + Math 확장 기능을 사용하기 위해 설치함
- 원래 미디어위키에서 무료로 제공하는 기본 Restbase서버와 Mathoid 서버를 이용해도 되지만, 속도가 정말 끔찍하게 느려서 직접 구축
- 제대로 된 문서가 없어서 구축 삽질 엄청 했다... 코드 안에 mediawiki url 하드코딩이 너무 많아 뭐가 문제인지 발견하기가 힘들었다
역할
- 미디어위키의 API를 처리하기 위한 REST 처리 서버
- REST로 받은 요청을 내부 독립 서버 (Parsoid, Mathoid 등)에 전달 및 반환 결과 캐싱
- 기본 DB 세팅인 SQLite는 동시에 많은 요청이 들어오면 db파일이 죽는 경우가 있어서, Cassandra 세팅으로 바꿈
- Node.js
레포지토리
- 인터넷에 떠도는 Dockerfile 기반으로 몇 가지 하드코딩을 넣어 이미지 생성
- Dockerfile
- Restbase 소스 (하드코딩 + 버그 수정)
- 도커 레포지토리
컨테이너 설정
- 포트 설정
- (비공개):7231
- 볼륨 설정
- config.yaml -> /mount/config.yaml
- 환경 변수
- (기본값)
미디어위키 Parsoid (도커)
역할
- 미디어위키의 Visual Editor 등에서 html <-> wikitext 간 변환 등을 위해 문서 실시간 파싱 등을 처리
- Node.js
레포지토리
- 인터넷에 떠도는 Dockerfile 기반으로 몇 가지 하드코딩을 넣어 이미지 생성
- Dockerfile
- Restbase 소스 (하드코딩 + 버그 수정)
- 도커 레포지토리
컨테이너 설정
- 포트 설정
- (비공개):8000
- (비공개):8001
- 볼륨 설정
- config.yaml -> /mount/config.yaml
- 환경 변수
- (기본값)
미디어위키 Mathoid (도커)
역할
- 미디어위키의 Math 확장 기능에서 사용
- LaTeX 문법을 svg, png 등으로 변환
- Node.js 10
레포지토리
- 인터넷에 떠도는 Dockerfile 기반으로 몇 가지 하드코딩을 넣어 이미지 생성
- Dockerfile
- Restbase 소스 (하드코딩 + 버그 수정)
- 도커 레포지토리
컨테이너 설정
- 포트 설정
- (비공개):10042
- 볼륨 설정
- config.yaml -> /mount/config.yaml
- 환경 변수
- (기본값)
Deluge (토렌트) (도커)
역할
- 토렌트 서버
- 컨테이너를 완전히 OpenVPN으로 감싸서, VPN 등록이 되지 않은 상태에서는 네트워크 접속을 원천 차단
레포지토리
컨테이너 설정
- 포트 설정
- (기본값)
- 볼륨 설정
- config/ -> /config
- (자료 저장 폴더) -> /data
- 환경 변수
- NAME_SERVERS = 1.1.1.1
- LAN_NETWORK = 호스트의 아이피 말고 호스트의 서브넷 (xxx.xxx.xxx.xxx/xx)
- ENABLE_PRIVOXY = yes
- PGID = 100
- PUID = 1026
- VPN_PROV = custom
- VPN_ENABLED = yes
- HOME = /config/home
- busybox
- gitlab
- gitlab postgresql
- redis
- DB
- cassandra 3.5
- mysql5.7.29
- wordpress
- kb_apart
권한 관련
LDAP
백업