Create TOC

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

2021년 10월 25일

img 파일 mount

raspberry pi OS의 /boot폴더가 손상될 경우 부팅이 안된다. 이때 새로 설치하지 않고 raspberry pi OS에서 /boot만 추출해서 복구해본다.

mount를 위해서 offset 값을 구해야 한다. 우선 fdisk 명령으로 시작 sector (Start)와 크기(Secror size)를 구한다.

$ sudo fdisk -l 2021-05-07-raspios-buster-armhf-lite.img
Disk 2021-05-07-raspios-buster-armhf-lite.img: 1.75 GiB, 1874853888 bytes, 3661824 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x9730496b

Device                                    Boot  Start     End Sectors  Size Id Type
2021-05-07-raspios-buster-armhf-lite.img1        8192  532479  524288  256M  c W95 FAT32 (LBA)
2021-05-07-raspios-buster-armhf-lite.img2      532480 3661823 3129344  1.5G 83 Linux

8192에 512를 곱한 수를 offset으로 사용한다.

$ sudo mount -o loop,offset=$((8192*512)) 2021-05-07-raspios-buster-armhf-lite.img /mmt/test

2020년 8월 29일

Raspberry Pi4/몇 가지 팁

wifi/bluetooth 끄기

/boot/config.txt에 dtoverlay=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월 20일

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년 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 형식으로 자동 프록시를 등록하면 된다.

2019년 12월 26일

Raspbian/docker + mariadb

Raspbian에서 mariadb를 docker로 올리는 방법을 기술한다.

docker-compose.yml

/docker/mariadb/config에 설정을 저장하는 것으로 설정 파일을 구성한다. 이 경로는 원하는 곳으로 바꾸면 된다.

root의 초기 비밀 번호는 ROOT_ACCESS_PASSWORD 로 설정했다.

db 관리를 위해 adminer도 같이 설치한다. mariadb가 구동되는 ip를 x.x.x.x 라고 가정했다.

version: "3"

services:
    mariadb:
        container_name: mariadb
        image: linuxserver/mariadb
        ports:
            - '3306:3306/tcp'
        environment:
            - TZ=Asia/Seoul
            - PUID=1001
            - PGID=1001
            - MYSQL_ROOT_PASSWORD=ROOT_ACCESS_PASSWORD
        volumes:
            - '//docker/mariadb/config/:/config/'
        restart: unless-stopped

    adminer:
        container_name: adminer
        image: adminer
        ports:
            - '8080:8080/tcp'
        environment:
            - TZ=Asia/Seoul
            - ADMINER_DEFAULT_SERVER=x.x.x.x
            - ADMINER_PLUGINS=tables-filter tinymce
        restart: unless-stopped

실행

docker-compose 명령으로 실행한다.

$ sudo docker-compose up -d

실행이 잘 되면 바로 root의 비밀번호를 변경한다.

$ sudo docker exec -it mariadb mysqladmin -u root -p password '새비밀번호'
Enter password:

이제 http://x.x.x.x:8080 으로 접속하면 웹으로 db를 관리할 수 있다.

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

2019년 6월 27일

Rasbian/Stretch에서 Buster로 판올림하기

Raspbian을 Stretch에서 Buster로 판올림한다.

source list 수정

/etc/apt/sourcelist.list 파일과 /etc/apt/sourcelist.d/ 디렉토리의 모든 파일에서 stretch 를 buster 로 변경한다.

패키지 목록 갱신

아래 명령으로 패키지 목록을 갱신 한다.

$ sudo apt update

이때 GPG 오류가 발생할 수 있다.

W: GPG Error http://deb.debian.org/debian buster-backports InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 7638D0442B90D010 NO_PUBKEY 04EE7237B7D453EC
E: The repository 'http://deb.debian.org/debian buster-backports InRelease' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.

우선 keyring package를 설치하고 다시 시도 해본다

$ sudo apt install debian-keyring raspbian-archive-keyring
$ sudo apt update

여전히 오류가 발생한다면 오류 메시지 중 NO_PUBKEY 뒤 문자열을 가지고 key를 찾아 등록한다.

$ gpg --keyserver pgpkeys.mit.edu --recv-key 7638D0442B90D010
$ gpg -a --export 7638D0442B90D010 | sudo apt-key add -
$ gpg --keyserver pgpkeys.mit.edu --recv-key 04EE7237B7D453EC
$ gpg -a --export 04EE7237B7D453EC | sudo apt-key add -

업그레이드

$ sudo apt upgrade
$ sudo apt dist-upgrade
$ sudo apt autoremove

버전 확인은 /etc/debianversion_ 파일 내용을 확인하면 된다.

$ cat /etc/debian_version
10.0

2019년 3월 13일

Raspbian/certbot 업그레이드

How to stop using TLS-SNI–01 with Certbot을 적용하려면 certbot 버전이 0.28 이상이어야 한다. 그러나 raspbian에 포함된 버전은 0.10 이다. 아래와 같은 방법으로 certbot을 업그레이드 한다.

우선 /etc/apt/sources.list.d/debian-stretch-backports.list 에 stretch-backports 를 추가한다.

deb http://deb.debian.org/debian stretch-backports main

업데이트 할 때 key 오류가 난다.

$ sudo apt-get update

...
W: GPG error: http://ftp.debian.org jessie-backports InRelease:
   The following signatures couldn't be verified because the public
   key is not available: NO_PUBKEY 8B48AD6246925553 NO_PUBKEY
   7638D0442B90D010

아래 명령으로 key를 가져온다.

$ sudo gpg --keyserver pgp.mit.edu --recv-keys 8B48AD6246925553 7638D0442B90D010

결과 메시지에서 가져온 key 정보를 확인한다.


gpg: key 8B48AD6246925553: 28 signatures not checked due to missing keys
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key 8B48AD6246925553: public key "Debian Archive Automatic Signing Key (7.0/wheezy) <ftpmaster@debian.org>" imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg:               imported: 1

가져온 키를 추가한다. 이때는 sudo 대신 root shell 에서 작업한다.

$ sudo -s
# gpg --armor --export 8B48AD6246925553 | apt-key add -

패키지 목록을 갱신하고 certbot을 업그레이드 한다.

$ sudo apt-get update
$ apt-get install certbot -t stretch-backports

2018년 5월 10일

pi-hole + DNSCrypt

DNSCrypt 설치 및 설청

아래와 같이 DNSCrypt를 설치한다.

$ wget https://github.com/jedisct1/dnscrypt-proxy/releases/download/2.0.11/dnscrypt-proxy-linux_arm-2.0.11.tar.gz
$ tar xvfz dnscrypt-proxy-linux_arm-2.0.11.tar.gz
$ mv linux-arm dnscrypt-proxy
$ sudo mv dnscrypt-proxy /opt

아래와 같이 예제 설정 파일을 복사한다.

$ cd /opt/dnscrypt-proxy
$ sudo cp example-dnscrypt-proxy.toml dnscrypt-proxy.toml

/opt/dnscrypt-proxy/dnscrypt-proxy.toml에서 원하는 설정을 변경하면 된다.

server_names = ['cloudflare', 'arvind-io', 'google']
listen_addresses = ['127.0.0.1:55', '[::1]:55']
require_dnssec = true

설정이 끝나면 아래 명령으로 서비스를 등록한다.

$ sudo /opt/dnscrypt-proxy/dnscrypt-proxy -service install

아래 명령으로 실행한다.

$ sudo systemctl start dnscrypt-proxy.service

pi-hole 설정

4.0 이상

4.0 부터는 DNS 서버를 dnsmasq를 사용하지 않기 때문에 pihole 설정을 직접 수정해야 한다. /etc/pihole/setupVars.conf파일에서 PIHOLE_DNS_1값을 수정한다.

PIHOLE_DNS_1=127.0.0.1#55

DNS 서버를 다시 시작한다.

$ sudo pihole restartdns

4.0 이전

/etc/dnsmasq.d/01-pihole.conf 파일에서 server=로 시작하는 줄을 아래와 같이 #을 붙여서 주석 처리 한다.

#server=1.1.1.1
#server=1.0.0.1

아래와 같은 내용으로 /etc/dnsmasq.d/02-dnscrypt.conf 파일을 만든다.

server=127.0.0.1#55

/etc/pihole/setupVars.conf 파일에서 PIHOLE_DNS로 시작하는 줄을 모두 주석 처리 한다.

그 후 dnsmasq를 재시작한다.

$ sudo systemctl restart dnsmasq.service

테스트

설정이 완료되면 DNSSEC Resolver Test 사이트에 접속해서 확인해본다.

2018년 5월 8일

pi-hole + DNS over HTTPS

Cloudflared 설치 및 설청

아래와 같이 CloudFlared를 설치한다.

$ wget https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-arm.tgz
$ tar xvfz cloudflared-stable-linux-arm.tgz
$ rm cloudflared-stable-linux-arm.tgz
$ sudo mv cloudflared /usr/local/bin

아래 명령을 실행해서 실행되는지 확인한다.

$ sudo cloudfalred proxy-dns --port 54 --upstream https://1.1.1.1/.well-known/dns-query --upstream https://1.0.0.1/.well-
known/dns-query

실행되는 것을 확인했으면 Ctrl-C로 중지 시키고 아래와 같은 내용으로 /usr/local/etc/cloudflared/config.yaml 파일을 만든다.

proxy-dns: true
proxy-dns-port: 54
proxy-dns-upstream:
 - https://1.1.1.1/.well-known/dns-query
 - https://1.0.0.1/.well-known/dns-query

서비스 등록을 위해 아래와 같은 내용으로 /etc/systemd/system/dnsproxy.service 파일을 만든다.

[Unit]
Description=CloudFlare DNS over HTTPS Proxy
Wants=network-online.target
After=network.target network-online.target

[Service]
ExecStart=/usr/local/bin/cloudflared
Restart=on-abort

[Install]
WantedBy=multi-user.target

파일을 만든 후에는 아래 명령을 이용해 dnsproxy.service활성화시킨다.

$ sudo systemctl enable dnsproxy.service

아래 명령으로 실행한다.

$ sudo systemctl start dnsproxy.service

pi-hole 설정

4.0 이상

4.0 부터는 DNS 서버를 dnsmasq를 사용하지 않기 때문에 pihole 설정을 직접 수정해야 한다. /etc/pihole/setupVars.conf파일에서 PIHOLE_DNS_1값을 수정한다.

PIHOLE_DNS_1=127.0.0.1#54

DNS 서버를 다시 시작한다.

$ sudo pihole restartdns

4.0 이전

/etc/dnsmasq.d/01-pihole.conf 파일에서 server=로 시작하는 줄을 아래와 같이 #을 붙여서 주석 처리 한다.

#server=1.1.1.1
#server=1.0.0.1

아래와 같은 내용으로 /etc/dnsmasq.d/02-cloudflare.conf 파일을 만든다.

server=127.0.0.1#54

/etc/pihole/setupVars.conf 파일에서 PIHOLE_DNS로 시작하는 줄을 모두 주석 처리 한다.

그 후 dnsmasq를 재시작한다.

$ sudo systemctl restart dnsmasq.service

테스트

설정이 완료되면 DNSSEC Resolver Test 사이트에 접속해서 확인해본다.

2017년 3월 26일

Raspbian/RealVNC 를 설정

Raspbian에 RealVNC가 제공된다. 항상 X를 사용하지는 않기 때문에 Virtual Mode를 설정하면 되지만, vncserver-virtuald.service를 제대로 사용하려면 RealVNC 계정을 만들어야 한다.항상 X를 사용한다면 vncserver-x11-serviced.service을 사용하면 된다.

계정을 만들지 않고 Virtual Mode를 사용할 수 있도록 설정한다.

RealVNC 설치

$ sudo apt-get install realvnc-vnc-server

RealVNC 서비스 중지

$ sudo systemctl disable vncserver-x11-serviced.service
$ sudo systemctl disable vncserver-virtuald.service

스크립트 작성

vncserver-virtuald.service를 사용하지 않고 직접 vncserver-virtual 를 사용할 경우 접속한 X 환경에서 logoff 등을 할 경우 VNC 연결이 끊어지면서 vncserver-virtual 도 종료된다.

10초마다 vncserver-virtual 가 동작 중인지 검사해서 실행시키는 스크립트를 작성한다.

스크립트는 /usr/local/bin/loop_vnc.sh로 저장한다.

#!/bin/bash
if [ -x /usr/bin/vncserver-virtual ]; then
 while [[ true ]]; do
  PS_COUNT=`ps aux | grep Xvnc | grep $USER | grep -v grep | wc --lines`
  if [ 0  == $PS_COUNT ]; then
   /usr/bin/vncserver-virtual :0
  fi
  sleep 10s
 done
fi

부팅 설정

/etc/rc.local에 아래 내용을 추가해서 부팅 할 때 스크립트를 자동으로 시작하게 설정한다. 이 때 로그인을 원하는 계정 권한으로 실행해야 하기 때문에 sudo를 사용한다.

if [ -x /usr/local/bin/loop_vnc.sh ]; then
 sudo -H -u pi /usr/local/bin/loop_vnc.sh &
fi

2016년 12월 19일

Raspbian/L2TP 서버 설정

iOS VPN 정책이 바뀌면서 ipTime의 VPN 기능을 사용할 수 없게 되었다. iOS에서 VPN을 사용할 수 있도록 Raspberry Pi에 L2TP 서버 설정을 한다.

패키지 설치

$ sudo apt-get install openswan xl2tpd ppp lsof rng-tools

네트워크 설정

포트 포워딩

공유기에서 UDP 500, 4500 포트를 Raspberry PI로 포트포워딩 한다.

Raspbian 설정

우선 아래 명령들을 실행한다.

$ sudo -s
# iptables --table nat --append POSTROUTING --jump MASQUERADE
# echo "net.ipv4.ip_forward = 1" |  tee -a /etc/sysctl.conf
# echo "net.ipv4.conf.all.accept_redirects = 0" |  tee -a /etc/sysctl.conf
# echo "net.ipv4.conf.all.send_redirects = 0" |  tee -a /etc/sysctl.conf
# for vpn in /proc/sys/net/ipv4/conf/*; do echo 0 > $vpn/accept_redirects; echo 0 > $vpn/send_redirects; done
# exit

설정이 잘 되어있는지 확인한다.

$ sudo sysctl -p

부팅시에도 설정이 동작하도록 /etc/rc.local 파일에 아래 내용을 추가한다.

for vpn in /proc/sys/net/ipv4/conf/*; do echo 0 > $vpn/accept_redirects; echo 0 > $vpn/send_redirects; done
iptables --table nat --append POSTROUTING --jump MASQUERADE

L2TP 설정

openswan 설정

예제 설정을 복사한다.

$ sudo cp /etc/ipsec.d/examples/l2tp-psk.conf  /etc/ipsec.d/l2tp-psk.conf

/etc/ipsec.conf파일을 열어서 맨 마지막에 아래 줄을 추가한다.

include /etc/ipsec.d/l2tp-psk.conf

그리고 protostack 값을 찾아서 아래와 같이 바꾼다.

protostack=netkey

/etc/ipsec.d/l2tp-psk.conf 파일을 열어서 아래 값들을 바꾼다.

conn L2TP-PSK-noNAT
 dpddelay=30
 dpdtimeout=120
 left=
 leftprotoport=17/%any
 forceencaps=yes

conn passthrough-for-non-l2tp
 left=
 leftnexthop=<공유기 내부 IP 주소>

/var/lib/openswan/ipsec.secrets.inc 파일을 편집에서 서버 접속시 사용할 비밀문자열을 지정한다.

192.168.1.112  %any:   PSK "복잡한문자열"

설정에 문제가 없는지 확한다.


$ sudo ipsec verify

xl2tpd 설정

/etc/xl2tpd/xl2tpd.conf파일을 열어 아래 값들을 바꾼다.

[global]
ipsec saref = yes

[lns default]
ip range = <할당하고 싶은 ip 대역. 192.168.0.201-192.168.0.250>
length bit = yes
require chap = yes
refuse pap = yes
name = <적당한이름. MyVPN>
pppoptfile = /etc/ppp/options.l2tpd.lns

아래와 같은 내용으로 /etc/ppp/options.l2tpd.lns파일을 만든다.

ipcp-accept-local
ipcp-accept-remote
require-mschap-v2
ms-dns 8.8.8.8
ms-dns 8.8.4.4
asyncmap 0
auth
crtscts
lock
idle 1800
mtu 1200
mru 1200
modem
debug
name l2tpd
proxyarp
lcp-echo-interval 30
lcp-echo-failure 4
nodefaultroute
connect-delay 5000

/etc/ppp/chap-secrets 파일을 열어서 접속할 때 사용할 id, 비밀번호를 설정한다.

# Secrets for authentication using CHAP
# client    server  secret          IP addresses

아이디 l2tpd   비밀번호   *

서비스 설정

$ sudo update-rc.d -f ipsec remove
$ sudo update-rc.d ipsec defaults

서비스 재시작

$ sudo /etc/init.d/xl2tpd restart
$ sudo /etc/init.d/ipsec restart

2016년 11월 28일

nginx에 let's encrypt 인증서 적용

/etc/nginx/sites-available에 원하는 이름의 설정 파일을 만들고 아래와 같이 설정한다.

server {
 listen 443 ssl;
 listen [::]:443 ssl;
 server_name 서버명;
 root /var/www/html;

 add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
 add_header X-Frame-Options DENY;
 ssl on;
 ssl_certificate /etc/letsencrypt/live/서버명/fullchain.pem;
 ssl_certificate_key /etc/letsencrypt/live/서버명/privkey.pem;

 #OCSP Stapling
 ssl_dhparam /etc/nginx/ssl/서버명.dhparam;
 ssl_stapling on;
 ssl_stapling_verify on;
 ssl_trusted_certificate /etc/letsencrypt/live/서버명/fullchain.pem;
 resolver 8.8.8.8 8.8.4.4;

 ssl_protocols   TLSv1 TLSv1.1 TLSv1.2;
 ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128  -GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECD  HE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-  SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES25  6-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

 ssl_prefer_server_ciphers on;
 ssl_session_timeout 1d;
 ssl_session_cache shared:SSL:10m;

 # 이후 원하는 설정 추가
}

dhparam파일도 만든다.

$ sudo mkdir /etc/nginx/ssl
$ sudo openssl dhparam -out /etc/nginx/ssl/서버명.dhparam 2048

서버 설정 파일을 활성화시킨다

$ sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/

설정에 문제가 없는지 테스트 해본다.

$ sudo nginx -t

Raspbian/Let's encrypt 설정

Raspbian에서 Let's encrypt 인증서를 설치하는 방법을 기술한다.

letsencrypt 설치

$ sudo -s
# gpg --keyserver pgpkeys.mit.edu --recv-key  8B48AD6246925553      
# gpg -a --export 8B48AD6246925553 | apt-key add -
# gpg --keyserver pgpkeys.mit.edu --recv-key 7638D0442B90D010      
# gpg -a --export 7638D0442B90D010 | apt-key add -
# echo "deb http://httpredir.debian.org/debian jessie-backports main contrib non-free" > /etc/apt/sources.list.d/debian-jessie-backports.list
# exit
$ sudo apt-get update
$ sudo apt-get install letsencrypt -t jessie-backports

인증서 생성

인증서 생성 전에 외부에서 433 포트로 접속 가능하도록 설정해야 한다.

$ sudo letsencrypt certonly --agree-tos --email 이메일주소 --standalone --domains 서버명

생성에 성공하면 /etc/letsencrypt/archive/서버명 디렉토리에 인증서가 저장되고 /etc/letsencrypt/live 디렉토리에 링크가 생성된다.

인증서 갱신

apt-get으로 letsencrypt을 설치한 경우에는 /etc/cron.d/certbot이 등록되기 때문에 갱신에 대해 따로 설정하지 않아도 된다.

현재 환경에서 인증서 갱신이 되는지는 아래 명령으로 테스트해보면 된다.

$ sudo cert-bot renew --dry-run

2016년 10월 11일

Raspbian/ffmpeg 빌드

raspiberry pi 3에서 사용할 ffmpeg를 빌드하는 방법을 설명한다.

빌드 환경 구성

패키지 설치

$ apt-get install git cmake build-essential libomxil-bellagio-dev libx264-dev libass-dev libfreetype6-dev libmp3lame-dev

MMAL 설치

$ git clone https://github.com/raspberrypi/userland.git
$ cd userland
$ ./buildme

빌드된 파일은 /opt/vc에 설치된다.

빌드

$ sudo apt-get install  libx264-dev libass-dev libfreetype6-dev libmp3lame-dev
$ git clone git://source.ffmpeg.org/ffmpeg.git
$ cd ffmpeg
$ ./configure --enable-libfreetype --enable-gpl --enable-nonfree --enable-libx264 --enable-libfaac --enable-libmp3lame --bindir=/usr/local/bin --enable-static --enable-omx-rpi --enable-mmal
$ make -j4
$ sudo make install

빌드가 완료되면 아래와 같이 실행해서 codec을 확인해본다.

$ ffmpeg -codecs | grep "\(mmal\|omx\)"
ffmpeg version N-81883-gbeb877b Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 4.9.2 (Raspbian 4.9.2-10)
  configuration: --enable-libfreetype --enable-gpl --enable-nonfree --enable-libx264 --enable-libass --enable-libmp3lame --bindir=/usr/local/bin --enable-static --enable-omx-rpi --enable-mmal
  libavutil      55. 32.100 / 55. 32.100
  libavcodec     57. 60.101 / 57. 60.101
  libavformat    57. 51.102 / 57. 51.102
  libavdevice    57.  0.102 / 57.  0.102
  libavfilter     6. 63.100 /  6. 63.100
  libswscale      4.  1.100 /  4.  1.100
  libswresample   2.  2.100 /  2.  2.100
  libpostproc    54.  0.100 / 54.  0.100
 DEV.LS h264                 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_mmal ) (encoders: libx264 libx264rgb h264_omx )
 DEV.L. mpeg2video           MPEG-2 video (decoders: mpeg2video mpegvideo mpeg2_mmal )
 DEV.L. mpeg4                MPEG-4 part 2 (decoders: mpeg4 mpeg4_mmal )
 D.V.L. vc1                  SMPTE VC-1 (decoders: vc1 vc1_mmal )

Raspbian/Tvheadend 빌드

tvheadend에 h264_omx 코덱을 사용할 수 있게 빌드하는 방법을 기술한다.

빌드 환경 구성

$ apt-get install git cmake build-essential debhelper pkg-config fakeroot libavahi-client-dev libssl-dev libcurl4-gnutls-dev liburiparser-dev  libogg-dev libtheora-dev libvorbis-dev

빌드

$ git clone https://github.com/tvheadend/tvheadend.git
$ cd tvheadend

소스를 받고 빌드 전 아래와 같이 Makefile.ffmpeg 파일을 수정한다.

diff --git a/Makefile.ffmpeg b/Makefile.ffmpeg
index e07ef2d..ff99604 100644
--- a/Makefile.ffmpeg
+++ b/Makefile.ffmpeg
@@ -573,6 +573,9 @@ $(LIB_ROOT)/$(FFMPEG)/.tvh_build: \
                --enable-gpl \
                --extra-cflags="$(ECFLAGS)" \
                --extra-libs="$(ELIBS)" \
+               --enable-omx-rpi --enable-mmal \
+               --enable-decoder="h264_mmal" \
+               --enable-encoder="h264_omx" \
                --pkg-config="$(ROOTDIR)/support/pkg-config.ffmpeg" \
                $(foreach component,$(COMPONENTS),--enable-$(component)) \
                $(foreach extlib,$(EXTLIBS),--enable-$(extlib)) \

h264_omx가 profile을 지원하지 않기 때문에 transcoding.c파일도 수정해야 한다.

diff --git a/src/plumbing/transcoding.c b/src/plumbing/transcoding.c
index 630bb62..ffb9657 100644
--- a/src/plumbing/transcoding.c
+++ b/src/plumbing/transcoding.c
@@ -1347,8 +1347,11 @@ transcoder_stream_video(transcoder_t *t, transcoder_stream_t *ts, th_pkt_t *pkt)
       av_dict_set(&opts, "preset",  t->t_props.tp_vcodec_preset, 0);
       tvhinfo(LS_TRANSCODE, "%04X: Using preset %s", shortid(t), t->t_props.tp_vcodec_preset);

-      // All modern devices should support "high" profile
-      av_dict_set(&opts, "profile", "high", 0);
+      if (0 != strcmp(ocodec->name, "h264_omx"))
+         {
+        // All modern devices should support "high" profile
+        av_dict_set(&opts, "profile", "high", 0);
+      }

       if (t->t_props.tp_vbitrate < 64) {
         // encode with specified quality and optimize for low latency

Makefile.ffmpeg, transcoding.c 파일 수정이 끝나면 아래와 같은 방법으로 빌드한다.

$ AUTOBUILD_CONFIGURE_EXTRA=--enable-ffmpeg_static\ --disable-libx264_static\ --disable-libx265\ --disable-libvpx\ --disable-libtheora_static\ --disable-libvorbis_static\ --disable-bintray_cache ./Autobuild.sh

빌드가 완료되면 아래와 같이 패키지를 설치한다.

$ cd ..
$ sudo dpkg -i tvheadend_4.1-2261~ga9bc3bc-dirty_armhf.deb

2016년 7월 11일

raspberrypi-ui-mods 설치 후 pkexec 문제

raspberrypi-ui-mods 설치 후 pkexec에서 추가한 계정이 표시되지 않는다. sudo 관련 정책파일을 추가해서 발생하는 문제다. 아래처럼 정책 파일을 추가해주면 된다.
$ cd /etc/polkit-1/localauthority.conf.d
$ sudo cp 51-desktop-sudo.con 61-desktop-policy-fix.conf

2016년 6월 22일

Raspbian/autofs 설정

설치

$ sudo apt-get install autofs
$ sudo mkdir /etc/auto.master.d

설정

설정이 끝나면 autofs를 다시 시작해야 한다.

디버깅

설정을 수정하면서 테스트하고 싶을 때는 아래와 같이 디버깅 모드를 사용한다.

$ sudo systemctl stop autofs
$ sudo automount -f -d

usb storage

/media/sda1으로 mount 하도록 설정한다. 아래 설정은 미디어가 vfat으로 포맷된 것을 가정하고 작성되었다.

  1. /etc/auto.master.d/media.autofs파일을 만든다

    /media  /etc/auto.master.d/media --timeout 60
    
  2. /etc/auto.master.d/media파일을 만든다.

    sda1 -fstype=auto,async,nodev,nosuid,umask=000 :/dev/sda1
    

WebDav

/mnt/net/davfs/box으로 mount 하도록 설정한다.

  1. davfs2 패키지를 설치한다.

    $ sudo apt-get install davfs2
    
  2. /etc/davfs2/secrets에 접속할 webdav 정보를 추가한다.

  3. /etc/auto.master.d/davfs.autofs파일을 만든다.

    /mnt/net/davfs /etc/auto.master.d/davfs --timeout 60
    
  4. /etc/auto.master.d/davfs파일을 만든다.

    box -fstype=davfs,uid=${UID},gid=${GID},rw,noexec,user,async :https://dav.box.com/dav
    

Raspbian/DHT22 센서 사용하기

DHT22 센서는 GPIO 4에 연결했다고 가정한다.

pigpio

GPIO 에서 값을 읽으려면 root 권한이 펼요하지만 pigpio를 사용하면 사용자 계정에서도 값을 읽을 수 있다.

설치

$ sudo apt-get install pigpio python-pigpio

설정

$ sudo systemctl enable pigpiod.service

시작

$ sudo systemctl start pigpiod.service

DHT22.py

설치

pigpio 샘플에 DHT22 를 다루는 코드가 있다.

$ wget https://raw.githubusercontent.com/joan2937/pigpio/master/EXAMPLES/Python/DHT22_AM2302_SENSOR/DHT22.py

수정

DHT22.py에서 atexit 관련 코드를 삭제한다.

그리고 GPIO 4에서 값을 읽도록 코드를 수정한다.

@@ -254,7 +254,7 @@ if __name__ == "__main__":

    pi = pigpio.pi()

-   s = DHT22.sensor(pi, 22, LED=16, power=8)
+   s = DHT22.sensor(pi, 4)

    r = 0

테스트

$ python DHT22.py
1 54.0 28.5 0.20 0 0 0 0
2 54.5 28.5 0.20 0 0 0 0
3 54.6 28.5 0.20 0 0 0 0
4 54.7 28.5 0.20 0 0 0 0

2016년 5월 22일

Raspbian/python과 pypy에서 pip 각각 사용하기

package가 아니고 따로 pip를 설치했다면 제거한다.


$ sudo pip uninstall pip

python을 위해 pip package 설치한다.


$ sudo apt-get install python-pip

pypy를 위해서 pip를 설치한다.


$ wget https://bootstrap.pypa.io/get-pip.py
$ sudo pypy get_pip.py

python과 pypy를 위한 alias를 ~/.bash_aliases에 만든다.


alias pip = 'sudo -H python -m pip'
alias pypy_pip = 'sudo -H pypy -m pip'