Create TOC

2020년 11월 29일

KDE/일출, 일몰에 따라 자동으로 테마 변경하기

KDE에는 일출, 일몰에 따라 자동으로 테마를 변경하는 설정이 없어서 따로 스크립트를 만들어서 변경한다.

일몰, 일출 시간을 얻기 위해서 python3-astral 패키지를 설치한다.

$ sudo apt install python3-astral

아래 python 스크립트를 ~/.local/bin/lookandfeel_change.py 으로 저장한다.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# vim:set expandtab fenc=utf-8 ff=unix:

import os
import logging
import datetime
import subprocess
import argparse
from astral import Astral  # type:ignore


logging.basicConfig(format='[%(asctime)s]{%(name)s}(%(levelname)s) %(message)s', level=logging.INFO)
logger = logging.getLogger(os.path.basename(__file__))
KST = datetime.timezone(datetime.timedelta(hours=9))

DARK_THEME = 'org.kde.breezedark.desktop'
LIGHT_THEME = 'org.kde.breeze.desktop'


def kreadconfig(group: str, key: str) -> str:
    p = subprocess.run(['/usr/bin/kreadconfig5', '--group', group, '--key', key],
                       capture_output=True)
    return p.stdout.decode('utf-8').strip()


def kwriteconfig(group: str, key: str, value: str):
    p = subprocess.run(['/usr/bin/kwriteconfig5', '--group', group, '--key', key, value],
                       capture_output=True)
    logger.debug(p.stdout.decode('utf-8').strip())
    logger.debug(p.stderr.decode('utf-8').strip())


def apply_theme(theme: str):
    p = subprocess.run(['/usr/bin/lookandfeeltool', '-a', theme], capture_output=True)
    logger.debug(p.stdout.decode('utf-8').strip())
    logger.debug(p.stderr.decode('utf-8').strip())
    kwriteconfig('KDE', 'LookAndFeelPackage', theme)


def main():
    ast = Astral()
    city = ast['Seoul']
    now = datetime.datetime.now(tz=KST)
    today = city.sun(date=now, local=True)
    logger.debug(f'{today["sunrise"]} <= {now} < {today["sunset"]}')

    new_theme = DARK_THEME
    if (today['sunrise'] <= now < today['sunset']):
        new_theme = LIGHT_THEME

    cur_theme = kreadconfig('KDE', 'LookAndFeelPackage')

    if cur_theme != new_theme:
        apply_theme(new_theme)
        logger.debug(f'apply {new_theme}')
    else:
        logger.debug(f'already applied {cur_theme}')


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='일출/일몰시간을 기준으로 Plasma 테마를 변경')

    parser.add_argument('--debug', '-d', action='store_true')

    options = parser.parse_args()

    if options.debug:
        logger.setLevel(logging.DEBUG)

    main()

저장 후 실행 속성을 준다.

$ chmod +x ~/.local/bin/lookandfeel_change.py

이대로 cron에 등록하면 제대로 동작하지 않는다. cron으로 실행하는 경우 login 했을 때와 환경 변수 구성이 다르기 때문이다. 아래 script를 ~/.local/bin/lookandfeel_change.sh으로 저장한다.

#!/bin/bash

export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/계정id/bus
export DESKTOP_SESSION=plasma
export DISPLAY=:0
export PATH=/home/계정명/.local/bin:/usr/local/bin/:/usr/local/bin:/usr/bin:/bin:/usr/games
export SHELL=/bin/bash
export XDG_CURRENT_DESKTOP=KDE
export XDG_RUNTIME_DIR=/run/user/계정id
export XDG_DATA_DIRS=/var/lib/flatpak/exports/share:/usr/local/share:/usr/share

/home/계정명/.local/bin/lookandfeel_change.py

계정id는 id 명령으로 확인할 수 있다. Debian 계열인 경우 첫번째로 추가한 사용자 id는 보통 1000 이다.

$ id

저장 후 실행 속성을 준다.

$ chmod +x ~/.local/bin/lookandfeel_change.sh

이제 10분마다 실행할 수 있게 crontab에 등록한다.

*/10 * * * * /home/계정명/.local/bin/lookandfeel_change.sh

Debian/anbox

Debian Sid에 anbox를 설치하고 playstore 설치하는 방법을 기술한다.

anbox설치

$ sudo apt install anbox

android 이미지 설치

anbox 패키지에는 android 이미지를 가지고 있지 않다. 아래와 같이 파일을 받아서 /var/lib/anbox에 넣어줘야 한다.

$ wget https://build.anbox.io/android-images/2018/07/19/android_amd64.img
$ sudo mv android_amd64.img /var/lib/anbox/android.img

PlayStore 설치

install-playstore.sh스크립트를 받아서 설치한다.

$ sudo apt install lzip squashfs-tools
$ wget https://raw.githubusercontent.com/geeks-r-us/anbox-playstore-installer/master/install-playstore.sh
$ sudo mkdir /etc/systemd/system/anbox-container-manager.service.d/
$ sudo bash install-playstore.sh
$ sudo apt purge lzip squashfs-tools

설치가 끝나면 아래와 같이 실행하고

$ anbox launch --package=org.anbox.appmgr --component=org.anbox.appmgr.AppViewActivity

Settings를 실행하고 Apps > Google Play Services > Permissions 에서 모든 권한을 주면 된다.

실행 예

설치해보면 실행 안되는 앱이 꽤 많다.

ESCline

네이버 카페

2020년 11월 18일

Debian/rclone + autofs

rclone mount을 autofs에 적용하는 방법을 기술한다.

rclone 으로 myremote remote 설정을 추가했다고 가정한다.

설치

$ sudo apt install autofs fuse3

rclonefs

rclone mount helper 스크립트는 한글 locale 에서 제대로 동작하지 않는다. 아래와 같이 수정해서 /usr/local/bin/rclonefs로 저장한다.

#!/bin/bash
remote=$1
mountpoint=$2
shift 2

# Process -o parameters
while getopts :o: opts; do
	case $opts in
		o)
			params=${OPTARG//,/ }
			for param in $params; do
				if [ "$param" == "rw"   ]; then continue; fi
				if [ "$param" == "ro"   ]; then continue; fi
				if [ "$param" == "dev"  ]; then continue; fi
				if [ "$param" == "suid" ]; then continue; fi
				if [ "$param" == "exec" ]; then continue; fi
				if [ "$param" == "auto" ]; then continue; fi
				if [ "$param" == "nodev" ]; then continue; fi
				if [ "$param" == "nosuid" ]; then continue; fi
				if [ "$param" == "noexec" ]; then continue; fi
				if [ "$param" == "noauto" ]; then continue; fi
				if [[ $param == x-systemd.* ]]; then continue; fi
				trans="$trans --$param"
			done
			;;
		\?)
			echo "Invalid option: -$OPTARG"
			;;
	esac
done

# exec rclone
trans="$trans $remote $mountpoint"
# NOTE: do not try "mount --daemon" here, it does not play well with systemd automount, use '&'!
# NOTE: mount is suid and ignores pre-set PATHs -> specify explicitely
PATH=$PATH rclone mount $trans /dev/null 2>/dev/null &

# WARNING: this will loop forever if remote is actually empty!
until [ "`LANG=C \ls -l $mountpoint`" != 'total 0' ]; do
	sleep 1
done

저장 후 실행 권한을 준다.

$ sudo chmod +x /usr/local/bin/rclonefs

autofs 설정

cloud.autofs

아래 내용으로 /etc/auto.master.d/cloud.autofs파일을 만든다.

/cloud	/etc/auto.master.d/auto.rclone

auto.rclone

아래 내용을 참고로 /etc/auto.master.d/auto.rclone 파일을 만든다.

myremotedrive	-fstype=fuse.rclonefs,config=/home/$USER/.config/rclone/rclone.conf,allow-other,uid=$UID	:myremote:

설정 적용

autofs를 다시 시작한다.

$ sudo systemctl restart autofs.service

테스트

아래 명령으로 myremote 내용이 잘보이는지 확인해본다.

$ ls /cloud/myremotedrive

Debian/ZSwap 설정

initramfs 설정

z3fold를 추가한다.

$ sudo -s
# echo z3fold >> /etc/initramfs-tools/modules
# update-initramfs -u

grub 설정

/etc/default/grub 파일을 편집한다.

$ sudo vi /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULTzswap.enabled=1zswap.zpool=z3fold를 추가한다.

GRUB_CMDLINE_LINUX_DEFAULT="quiet zswap.enabled=1 zswap.zpool=z3fold"

grub 설정을 반영한다.

$ sudo update-grub

2020년 11월 8일

Debian/VirtualBox의 VRDE 설정

VNC 비밀 번호 설정

Debian에서 VirtualBox 패키지만 설치한 경우 원격디스플레이를 VNC를 사용할 수 있다. 단, 이때 VNC 비밀번호를 설정해줘야 한다.

$ VBoxManage modifyvm "가상머신 이름" --vrdeproperty VNCPassword=비밀번호

가상머신 이름은 아래와 같이 찾을 수 있다.

$ VBoxManage list vms

RDP 사용

우선 virtualbox-ext-pack을 설치한다.

$ sudo apt install virtualbox-ext-pack

VNC 대신 RDP를 사용하고 싶은 가상머신에 대해서 아래와 같이 설정한다.

$ VBoxManage modifyvm "가상머신 이름" --vrdeextpack "Oracle VM VirtualBox Extension Pack"

기본값으로 되돌리고 싶으면 아래와 같이 입력한다

$ VBoxManage modifyvm "가상머신 이름" --vrdeextpack default

2020년 9월 11일

python개발을 위한 code-server 설정

code-server를 이용해 웹 브라우저로 접속하는 vscode 환경을 만든다.

https 연결은 caddy을 사용한다.

docker-compose.yml

cdr-python 이미지 까지 빌드할 수 있게 docker-compose.yml파일을 구성한다.

version: "3"

services:
    app:
        build:
            context: ./cdr_build
            dockerfile: Dockerfile
        image: cdr-python
        user: "1001:1001"
        expose:
            - 8080
        environment:
            - PASSWORD=비밀번호
        volumes:
            - '작업폴더:/home/coder/project'
        restart: unless-stopped
    caddy:
        image: caddy
        ports:
            - '포트:포트/tcp'
        environment:
            - ACME_AGREE=false
            - DOMAIN=도메인
            - CADDY_PORT=포트
        volumes:
            - ./Caddyfile:/etc/caddy/Caddyfile:ro
            - ./caddy_data:/data
            - /etc/letsencrypt:/etc/letsencrypt:ro
        restart: unless-stopped

Caddyfile

https 접속을 위해 Caddyfile을 만든다.

(forwardheaders) {
    header_up X-Forwarded-Ssl on
    header_up Host {host}
    header_up X-Real-IP {remote}
    header_up X-Forwarded-For {remote}
    header_up X-Forwarded-Port {server_port}
    header_up X-Forwarded-Proto {scheme}
    header_up X-Url-Scheme {scheme}
    header_up X-Forwarded-Host {host}
}

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

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

    root * /var/www
    file_server

    rewrite /cdr /cdr/

    route /cdr/* {
        uri strip_prefix /cdr
        reverse_proxy app:8080 {
            import forwardheaders
        }
    }

    respond /robots.txt "User-agent: *\nDisallow: /" 200 {
        close
    }
}

cdr-python 이미지 빌드

Dockerfile

cdr_build 디렉토리를 만들고 아래와 같은 DockerFile을 만든다. 필요한 extension은 미리 cdr_build에 복사한다.

FROM codercom/code-server:latest

COPY *.vsix /tmp/
RUN sudo chmod 666 /tmp/*.vsix
RUN code-server --install-extension /tmp/indent-rainbow.vsix && \
 code-server --install-extension /tmp/rainbow-brackets.vsix && \
 code-server --install-extension /tmp/dracula.vsix
RUN code-server --install-extension /tmp/python.vsix
RUN code-server --install-extension /tmp/pyright.vsix
RUN sudo rm -f /tmp/*.vsix
RUN sudo apt-get update && \
 sudo apt-get -y install python3-pip \
 python3-bs4 \
 python3-lxml \
 python3-requests \
 python3-flake8 \
 python3-mypy \
 python3-sqlalchemy

시작

$ docker-compose up -d

테스트

웹브라우저를 사용해서 https://도메인:포트/cdr/ 에 접속해본다.

2020년 8월 29일

Raspberry Pi4/몇 가지 팁

wifi/bluetooth 끄기

/boot/config.txtdtoverlay=disable-wifi, dtoverlay=disable-bt를 추가한다.

[all]
dtoverlay=disable-wifi
dtoverlay=disable-bt

IPv6 끄기

sysctl 설정을 추가한다.

$ sudo vi /etc/sysctl.d/local.conf
# Disable IPv6
net.ipv6.conf.all.disable_ipv6 = 1

pigpiod 오류

IPv6를 끄면 pigpiod.service가 동작하지 않는다.V73에서는 수정되었다고 한다. /lib/systemd/system/pigpiod.service에서 pigpiod 에 -n 127.0.0.1 옵션을 추가해준다.

[Service]
ExecStart=/usr/bin/pigpiod -l -n 127.0.0.1

dhcp 서비스가 오류나면서 ip를 잃어버릴 때

docker를 사용하는 경우 아래와 같이 docker에서 사용하는 interface를 제외시킨다.

$ sudo vi /etc/dhcpcd.conf
denyinterfaces veth*

오류 발생시 고정 ip를 사용하도록 설정을 추가한다.

$ sudo vi /etc/dhcpcd.conf

# It is possible to fall back to a static IP if DHCP fails:
# define static profile
profile static_eth0
static ip_address=192.168.0.x/24
static routers=192.168.0.100
static domain_name_servers=1.1.1.1

# fallback to static profile on eth0
interface eth0
fallback static_eth0

2020년 7월 30일

Oracle Cloud VM 설정

VM instance 만들기

오라클 클라우드에서 평생 무료로 VPS 사용하기를 따라서 만들면 된다.

도메인 설정

컴퓨트 - 인스턴스에서 만든 인스턴스를 선택하고 공용 IP 주소를 확인해서 도메인 설정에 이용한다.

쉘 변경

$ sudo apt install zsh
$ sudo chsh -s /bin/zsh ubuntu

docker 환경 구성

$ sudo apt install docker-compose
$ sudo usermod -aG docker $USER

Let's Enctrypt 인증서 발급

방화벽 설정

컴퓨트 - 인스턴스에서 만든 인스턴스를 선택하고 기본 VNIC - 서브넷 - 보안 목록에서 사용 중인 보안 목록을 선택한 후, 수신 규칙 추가를 통해서 80 포트에 대한 수신 규칙을 추가한다.

인증서 발급

$ docker run -it --rm --name certbot -v '/etc/letsencrypt:/etc/letsencrypt' -p 80:80 certbot/certbot certonly --agree-tos --no-eff-email --standalone --preferred-challenges http -d 도메인

인증서 갱신

매번 컨테이너를 생성/삭제하기 귀찮아서 docker-compose를 사용했다.

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

version: "3"

services:
    certbot:
        container_name: certbot
        image: certbot/certbot
        ports:
            - "80:80/tcp"
        entrypoint: certbot renew
        volumes:
            - '/etc/letsencrypt:/etc/letsencrypt'

아래 명령으로 컨테이너를 실행한다.

$ docker-compose up

문제가 없다면 crontab에 등록해서 적당히 실행시켜 둔다

0 0 */2 * * docker-compose -f /home/ubuntu/docker/certbot/docker-compose.yml up

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
	}
}

Raspbian/Watchdog 설정

Raspberry pi에는 hardware watchdog timer가 있다. 이를 활용하면 문제가 발생했을 때 자동으로 재부팅시킬 수 있다.

watchdog timer가 있는지 확인안다.

$ dmesg | grep -i watchdog
[    0.399099] bcm2835-wdt bcm2835-wdt: Broadcom BCM2835 watchdog timer

/etc/systemd/system.conf 파일에서 RuntimeWatchdogSec 값과 ShutdownWatchdogSec 값을 바꾼다.

RuntimeWatchdogSec=15
RebootWatchdogSec=5min

재부팅 후 watchdog 설정이 적용된 것을 확인한다.

$ dmesg | grep -i watchdog
[    0.399099] bcm2835-wdt bcm2835-wdt: Broadcom BCM2835 watchdog timer
[    1.364292] systemd[1]: Hardware watchdog 'Broadcom BCM2835 Watchdog timer', version 0
[    1.364350] systemd[1]: Set hardware watchdog to 15s.

2020년 3월 4일

Andriod/자동 프록시 설정시 Goolge Play Store나 YouTube가 동작하지 않는 문제 수정

Andriod 기기에서 자동 프록시 (pac)를 설정하면 Google Play Store나 YouTube가 동작하지 않는다. 이때는 설정 - 앱 및 알림 - 배터리 최적화 (Optimize battery) 대상에서 ProxyHandler를 빼면 된다(최적화 하지 않음).

2020년 1월 3일

Raspbian/docker + GreenTunnel

raspbian에서 GreenTunnel을 docker로 올리는 방법을 기술한다.

docker image 만들기

GreenTunnel 소스를 받는다

$ git clone https://github.com/SadeghHayeri/GreenTunnel GreenTunnel

GreenTunnel/Dockerfile 파일에서 FROM 부분을 아래와 같이 수정한다.

FROM node:lts-buster-slim

이미지를 빌드한다.

$ cd GreenTunnel
$ sudo docker build --tag green-tunnel ./

이미지가 생성되었는지 확인한다.

$ sudo docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
green-tunnel                  latest              e0f67216c1d5        19 hours ago        158MB
node                          lts-buster-slim     b490682c0125        5 days ago          134MB

docker-compose.yml

version: "3"

services:
    green-tunnel:
        container_name: green-tunnel
        image: green-tunnel
        ports:
            - "8000:8000/tcp"
        restart: unless-stopped

docker-compose 명령으로 container를 만든다.

$ sudo docker-compose up -d

테스트

GreenTunnel을 실행시킨 raspberry pi의 ip와 port 8000 으로Firefox 등의 웹 브라우저의 proxy 설정에서 https proxy를 설정한다.

GreenTunnel 로그는 아래 명령으로 확인할 수 있다.

$ sudo docker logs -f green-tunnel

proxy.pac

이제 원하는 사이트에 접속할 때만 GreenTunnel 을 사용하도록 자동 프록시 설정 파일(proxy.pac)을 만든다.

예제는 https://abc*.net, https://def.net, 접속에서만 GreenTunnel을 사용하도록 설정했다.

function FindProxyForURL(url, host) {
    url = url.toLowerCase();
    host = host.toLowerCase();

    isHttp=(url.substring(0, 5) == "http:");

    if (isHttp) {
        return "DIRECT";
    }

    if (0
        || isPlainHostName(host)
        || shExpMatch(host, "*.local")
        || isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0")
        || isInNet(dnsResolve(host), "172.16.0.0",  "255.240.0.0")
        || isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0")
        || isInNet(dnsResolve(host), "127.0.0.0", "255.255.255.0")
        ) {
        return "DIRECT";
    }

    if (0
        || shExpMatch(url, "https://abc*.net/*")
        || shExpMatch(url, "https://def.net/*")
        ) {
        return "PROXY GreenTunnel주소:8000";
    }
    return "DIRECT";
}

proxy.pac을 http 로 접속 가능한 위치에 올리고 원하는 브라우저나 시스템 설정에서 http://어딘가/proxy.pac 형식으로 자동 프록시를 등록하면 된다.