Create TOC

레이블이 reverse proxy인 게시물을 표시합니다. 모든 게시물 표시
레이블이 reverse proxy인 게시물을 표시합니다. 모든 게시물 표시

2020년 7월 20일

Docker/Caddy 를 이용한 reverse proxy 설정

Caddy를 이용한 reverse proxy 설정을 기록한다. 인증서는 따로 /etc/letsencrypt에 갱신하기 때문에 그 인증서를 그대로 사용하게 설정했다.

bitwarden

https://mydomain.net:1234 -> bitwarden

docker-compose.yml

version: "3"

services:
    bitwarden:
        container_name: bitwarden
        image: bitwardenrs/server:raspberry
        environment:
            - WEBSOCKET_ENABLED=true
            - ./bitwarden_data:/data
        restart: unless-stopped
    caddy-bitwarden:
        container_name: caddy-bitwarden
        image: caddy
        ports:
            - '1234:1234/tcp'
        environment:
            - ACME_AGREE=false
            - DOMAIN=mydomain.net
            - CADDY_PORT=1234
            - REDIRECT_URL=bitwarden:80
        volumes:
            - ./Caddyfile:/etc/caddy/Caddyfile:ro
            - /etc/letsencrypt:/etc/letsencrypt:ro
        restart: unless-stopped

Caddyfile

{$DOMAIN}:{$CADDY_PORT} {
	tls /etc/letsencrypt/live/{$DOMAIN}/fullchain.pem /etc/letsencrypt/live/{$DOMAIN}/privkey.pem

	header / {
		Strict-Transport-Security "max-age=15768000;"
		X-XSS-Protection "1; mode=block"
		X-Frame-Options "DENY"
		X-Robots-Tag "none"
	}

	# The negotiation endpoint is also proxied to Rocket
	reverse_proxy /notifications/hub/negotiate bitwarden:80

	# Notifications redirected to the websockets server
	reverse_proxy /notifications/hub bitwarden:3012

	# Proxy the Root directory to Rocket
	reverse_proxy /* {$REDIRECT_URL}
}

nextcloud

https://mydomain.net:1234 -> php-fpm(nextcloud)

docker-compose.yml

version: '3.1'

services:
    nextcloud:
        image: nextcloud:fpm-alpine
        container_name: nextcloud
        environment:
            - TZ=Asia/Seoul
            - PUID=1001
            - PGID=1001
            - MYSQL_DATABASE=db이름
            - MYSQL_USER=mysql사용자이름
            - MYSQL_PASSWORD=mysql비밀번호
            - MYSQL_HOST=mysql서버주소
            - NEXTCLOUD_TRUSTED_DOMAINS=mydomain.net:1234
            - NEXTCLOUD_ADMIN_USER=nextcloud관리자이름
            - NEXTCLOUD_ADMIN_PASSWORD=nextcloud관리자비밀번호
        volumes:
            - ./nextcloud_html:/var/www/html
        restart: unless-stopped
    caddy-nextcloud:
        container_name: caddy-nextcloud
        image: caddy
        ports:
            - '1234:1234/tcp'
        environment:
            - ACME_AGREE=false
            - DOMAIN=mydomain.net
            - CADDY_PORT=1234
        volumes:
            - ./Caddyfile:/etc/caddy/Caddyfile:ro
            - ./nextcloud_html:/var/www/html:ro
            - /etc/letsencrypt:/etc/letsencrypt:ro
        restart: unless-stopped

Caddyfile

{$DOMAIN}:{$CADDY_PORT} {
	tls /etc/letsencrypt/live/{$DOMAIN}/fullchain.pem /etc/letsencrypt/live/{$DOMAIN}/privkey.pem

	header / {
		Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;"
		Referrer-Policy "no-referrer"
		X-Content-Type-Options "nosniff"
		X-Download-Options "noopen"
		X-Frame-Options "SAMEORIGIN"
		X-Permitted-Cross-Domain-Policies "none"
		X-Robots-Tag "none"
		X-XSS-Protection "1; mode=block"
	}

	root * /var/www/html
	file_server

	php_fastcgi nextcloud:9000

	header /core/fonts {
		Cache-Control "max-age=604800"
	}

	@phpFiles {
		path_regexp phpfile ^/(remote|public|cron|core/ajax/update|status|ocs/v1|ocs/v2)\.php
	}
	rewrite @phpFiles {http.regexp.phpfile.0}

	# Service discovery via well-known
	redir /.well-known/carddav /remote.php/carddav 301
	redir /.well-known/caldav /remote.php/caldav 301

	@forbidden {
		path	/.htaccess
		path	/data/*
		path	/config/*
		path	/db_structure
		path	/.xml
		path	/README
		path	/3rdparty/*
		path	/lib/*
		path	/templates/*
		path	/occ
		path	/console.php
	}

	respond @forbidden 404
}

path 제거

{$DOMAIN}:{$CADDY_PORT}/foo/ -> 172.16.10.5:449/

Caddyfile

{$DOMAIN}:{$CADDY_PORT} {
	tls /etc/letsencrypt/live/{$DOMAIN}/fullchain.pem /etc/letsencrypt/live/{$DOMAIN}/privkey.pem

	header / {
		# Enable HTTP Strict Transport Security (HSTS)
		Strict-Transport-Security "max-age=15768000;"
		X-Frame-Options "DENY"
		X-Robots-Tag "none"
	}

	route /foo/* {
		uri strip_prefix /foo
		reverse_proxy 172.16.10.5:449
	}
}

path 변경

{$DOMAIN}:{$CADDY_PORT}/foo/ -> 172.16.10.5:449/bar/

Caddyfile

{$DOMAIN}:{$CADDY_PORT} {
	tls /etc/letsencrypt/live/{$DOMAIN}/fullchain.pem /etc/letsencrypt/live/{$DOMAIN}/privkey.pem

	header / {
		# Enable HTTP Strict Transport Security (HSTS)
		Strict-Transport-Security "max-age=15768000;"
		X-Frame-Options "DENY"
		X-Robots-Tag "none"
	}

	route /foo/* {
		uri replace /foo/ /bar/
		reverse_proxy 172.16.10.5:449
	}
}

2019년 12월 16일

Raspbian/사용하던 서비스를 docker로 이전

기존에 사용하던 서비스를 docker로 옮기는 과정을 기술한다.

docker로 옮길 서비스는 아래와 같다.

  • certbot
  • pihole + dnscrypt
  • tvheadend
  • nginx
  • homebridge

docker 환경 구성

docker 설치

get-docker.sh 를 이용해 설치한다.

$ curl -fsSL get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh

docker 그룹에 계정을 추가하면 sudo 없이 docker를 실행할 수 있다.

$ usermod -aG docker pi
$ sudo mkdir /docker
$ chown pi /docker

docker-compose 설치

$ sudo apt-get install docker-compose

certbot

설정 옮김

$ mkdir /docker/certbot
$ sudo cp -R /etc/letsencrypt /docker/certbot/config

docker-compose.yml

아래와 같은 /docker/certbot/docker-compose.yml 파일을 만든다.

version: "3"

services:
    certbot:
        container_name: certbot
        image: tobi312/rpi-certbot
        ports:
            - "80:80/tcp"
            - "443:443/tcp"
        entrypoint: certbot renew
        volumes:
            - '/docker/certbot/config/letsencrypt:/etc/letsencrypt'

테스트

$ cd /docker/certbot
$ docker-compose up

문제 없다면 /docker/certbot/docker-compose.yml 파일에서 entrypoint 를 아래와 같이 변경한다.

entrypoint: certbot -q renew

cron

2일 간격으로 인증서 갱신을 위해 certbot을 실행하도록 /etc/cron.d/certbot 파일을 만든다.

0 0 */2 * * root test -x /usr/bin/docker-compose && perl -e 'sleep int(rand(43200))' && docker-compose -f /docker/certbot/docker-compose.yml up

pihole

dnscrypt-proxy-2 대신 cloudflared 를 사용하게 변경했다.

설정 옮김

$ mkdir -p /docker/pihole/
$ sudo cp -R /etc/dnsmasq.d /docker/pihole/config
$ sudo cp -R /etc/pihole /docker/pihole/config

설정 수정

/docker/pihole/config/dnsmasq.d/01-pihole.conf 파일에서 server 를 아래와 같이 수정한다.

server=10.0.0.2#54

/docker/pihole/config/pihole/setupVars.conf 파일에서 PIHOLE_DNS 를 아래와 같이 수정한다.

PIHOLE_DNS_1='10.0.0.2#54'PIHOLE_DNS_2=''

docker-compose.yml

아래와 같이 /docker/pihole/docker-compose.yml 파일을 만든다.

version: "3"

services:
    cloudflared:
        image: visibilityspots/cloudflared
        environment:
            - TZ=Asia/Seoul
        networks:
            pihole_net:
                ipv4_address: 10.0.0.2
        restart: unless-stopped

    app:
        image: pihole/pihole:latest
        ports:
            - '53:53/tcp'
            - '53:53/udp'
            - '8888:80/udp'
        environment:
            - TZ=Asia/Seoul
            - DNS1=10.0.0.2#54
            - DNS2=
            - DNSSEC=true
            - IPv6=false
            - PUID=1000
            - PGID=1000

        volumes:
            - '/docker/pihole/config/pihole/:/etc/pihole/'
            - '/docker/pihole/config/dnsmasq.d/:/etc/dnsmasq.d/'
        networks:
            pihole_net:
                ipv4_address: 10.0.0.3
        dns:
            - 127.0.0.1
            - 1.1.1.1
        restart: unless-stopped

networks:
    pihole_net:
        driver: bridge
        ipam:
            config:
                - subnet: 10.0.0.0/29

테스트

아래와 같이 기존 서비스를 중지하고 docker로 pihole 을 실행한다.

$ sudo systemctl stop dnscrypt-proxy.service
$ sudo pihole disable
$ cd /docker/pihole
$ docker-compose up -d

nslookup 으로 dns query가 잘 되는지 확인한다. 문제가 있다면 docker-compose -f /docker/pihole/docker-compose.yml logs app 명령으로 로그를 확인해 본다.

문제가 없는 것이 확인되면 설치되어 있던 dnscrypt-proxy-2와 pihole는 삭제한다.

기타

pihole-FTL 사용법

pihole-FTL은 아래와 같이 container에서 명령을 실행해서 사용할 수 있다.

$ docker-compose -f /docker/pihole/docker-compose.yml exec app bash -c 'echo ">stats" | nc -w 1 127.0.0.1 4711'

lighttpd 중지

안쓰는 웹서버는 아래 명령으로 중지해놓는다.

$ docker-compose -f /docker/pihole/docker-compose.yml exec app service lighttpd stop

tvheadend

설정 옮김

$ mkdir /docker/tvheadend
$ mkdir /docker/tvheadend/rec
$ sudo -s
# cd /home/hts/.hts
# tar cvfj /docker/tvheadend/tvh.tar.bz2 tvheadend
# exit
$ cd /docker/tvheadend
$ sudo tar xvfj tvh.tar.bz2
$ sudo mv tvheadend config
$ sudo rm tvh.tar.bz2

docker-compose.yml

아래와 같이 /docker/tvheaded/docker-compose.yml 파일을 만든다.

version: "3"

services:
    app:
        image: linuxserver/tvheadend
        ports:
            - "9981:9981/tcp"
            - "9982:9982/tcp"
        environment:
            - TZ=Asia/Seoul
            - PUID=1000
            - PGID=1000
        devices:
            - "/dev/dvb:/dev/dvb"
        volumes:
            - '/docker/tvheadend/config:/config'
            - '/docker/tvheadend/rec:/recordings'
        restart: unless-stopped

테스트

$ cd /docker/tvheadend
$ docker-compose up -d

문제

encoding 이슈

nginx

설정 옮김

기존 설치된 nginx 설정 구조와 docker image의 구조가 달라서 우선 docker image를 설치하고 설정을 수정한다.

docker-compose.yml

아래와 같이 /docker/nginx/docker-compose.yml 파일을 만든다.

version: "3"

services:
    app:
        image: linuxserver/nginx
        network_mode: host
        environment:
            - TZ=Asia/Seoul
            - PUID=1000
            - PGID=1000
        volumes:
            - '/docker/certbot/config/letsencrypt:/etc/letsencrypt'
            - '/docker/nginx/config:/config'
            - '/media/www:/mediw/www'
        restart: unless-stopped

설정 수정

우선 container를 실행한다.

$ cd /docker/nginx
$ docker-compose up -d

ssl

/etc/nginx/ssl 폴더가 있다면 /docker/nginx/config/nginx/ssl 로 복사

nginx

linuxserver/nginx 이미지를 그대로 사용하면 nginx에 많은 모듈이 동작하게 된다.

원하는 모듈만 동작하게 하기 위해 /docker/nginx/config/nginx/nginx.conf 파일에서 기존 /etc/nginx/modules/*.conf 대신 /config/nginx/modules/*.conf 를 사용하도록 수정한다.

# include /etc/nginx/modules/*.conf;
include /config/nginx/modules/*.conf;

/docker/nginx/config/nginx/modules 폴더를 만들고 원하는 모듈의 *.conf만 복사한다.

사용가능한 모듈의 conf는 아래 명령으로 확인할 수 있다.

$ docker-compose -f ~/docker/nginx/docker-compose.yml exec app ls /etc/nginx/modules

복사는 아래와 같이 한다.

$ docker-compose -f ~/docker/nginx/docker-compose.yml exec app cp /etc/nginx/modules/http_echo.conf /config/nginx/modules

site-confs

/docker/nginx/config/nginx/site-confs/default 파일 내용을 비우고 /etc/nginx/site-enabled 파일을 가져온다.

가져온 site 설정에서 아래 내용을 수정한다.

  1. /etc/nginx/ssl 부분을 /config/nginx/ssl 로 변경
  2. log 경로를 /config/nginx/log 로 변경
  3. auth_basic_user_file 을 사용하고 있었다면 파일 경로를 /config/nginx 아래로 변경하고 기존에 사용하던 auth_basic_user_file 을 /docker/nginx/config/nginx 의 정해둔 경로로 복사.

homebridge

설정 옮김

$ mkdir /docker/homebridge
$ cp -R ~/.homebridge /docker/homebridge/config

/docker/homebridge/config/startup.sh 파일을 만들고 설치할 package를 등록한다.

#!/bin/sh

if [ ! -f /homebridge/.install_done ]; then
    npm i miio
    npm i homebridge-websocket
    npm i homebridge-mi-fan
    npm i homebridge-mi-pm2_5
    npm i homebridge-http-temperature-humidity
    touch /homebridge/.install_done
fi;

docker-compose.yml

아래와 같이 /docker/nginx/docker-compose.yml 파일을 만든다.

version: "3"

services:
    app:
        image: oznu/homebridge:raspberry-pi
        network_mode: host
        environment:
            - TZ=Asia/Seoul
            - PUID=1000
            - PGID=1000
            - HOMEBRIDGE_INSECURE=1
            - HOMEBRIDGE_CONFig_UI=1
            - HOMEBRIDGE_CONFig_UI_PORT=18080
        volumes:
            - '/docker/homebridge/config:/homebridge'
        restart: unless-stopped

테스트

기존에 실행하던 homebridge를 중지하고 homebridge container를 실행한다.

$ cd /docker/homebridge
$ docker-compose up -d

로그를 확인해보고 web ui 접속도 해본다.

$ docker-compose -f /docker/homebridge/docker-compose.yml logs app

2016년 11월 18일

nginx에서 sub-directory에 proxy pass 설정

nginx에서 제공하는 reverse proxy기능을 사용하면 특정 sub-directory에 대한 응답을 다른 서버에서 가져와서 보여줄 수 있다.

아래와 같이 설정하면 http://내서버/abcde/foo.html 요청을 받는 경우 http://127.0.0.1:1245/foo.html 에서 내용을 가져와서 보여준다.


server {
 ....
 location /abcde/ {
  access_log off;
  error_log off;
  rewrite ^/abcde(/.*)$ $1 break;
  proxy_pass http://127.0.0.1:1245;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $remote_addr;
  proxy_redirect off;
 }
}