LibreELECでDebianを動かす

LibreELECはとてもコンパクトにまとまってて、プログラムを動かしたい場合リポジトリからインストールすることになります。ただ全て良い結果になるわけでありません。たとえばDockerをインストールしてDebianを動かしたい時、s905xではカーネルバージョンが3.14であるためoverlayfsが使えません。その結果、一見動いているようにみえますが、書き込みできないために再度立ち上げた時にエラーが起こります。

Error response from daemon: oci runtime error: container_linux.go:247: starting container process caused "exec: \"bash\": executable file not found in $PATH" 
Error: failed to start containers: mydebian

そこで苦肉の策としてchrootを使ってみます。LibreELECではaptが使えないのでPCのデスクトップでイメージを作ります。s905xはarm64なのでそのアーキティチャーにあったアーカイブを使います。

$ sudo mkdir -p $HOME/srv/chroot/stretch
$ sudo debootstrap --arch=armhf stretch mkdir -p $/HOME/srv/chroot/stretch http://ftp.debian.org/debian/
$ cd $HOME
$ sudo tar czvf $HOME/strech.tar.gz ./srv/chroot/stretch

scp等でTV BOXに移して展開します。

# cd /storage
# tar xzvf strech.tar.gz

Debianのレポジトリを編集します。

/storage/srv/chroot/stretch/etc/apt/sources.list

deb http://ftp.jp.debian.org/debian/ stretch main contrib non-free 
deb-src http://ftp.jp.debian.org/debian/ stretch main contrib non-free

chroot用のスクリプトを作ります。

chroot.sh

#!/usr/bin/sh 
 
CHROOT=/storage/srv/chroot/stretch 
 
mount -o bind /proc $CHROOT/proc 
mount -o bind /sys $CHROOT/sys 
mount -o bind /dev $CHROOT/dev 
mount -o bind /dev/shm $CHROOT/dev/shm 
mount -o bind /dev/pts $CHROOT/dev/pts 
mount -o bind /sys/kernel/debug $CHROOT/sys/kernel/debug 
mount -o bind /sys/kernel/config $CHROOT/sys/kernel/config 
mount -o bind /dev/mqueue $CHROOT/dev/mqueue 

chroot $CHROOT /usr/bin/env -i \ 
    HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \ 
    PATH=/bin:/usr/bin:/sbin:/usr/sbin \ 
    /bin/bash --login +h 
 
umount $CHROOT/dev/mqueue 
umount $CHROOT/sys/kernel/config 
umount $CHROOT/sys/kernel/debug 
umount $CHROOT/dev/pts 
umount $CHROOT/dev/shm 
umount $CHROOT/dev 
umount $CHROOT/sys 
umount $CHROOT/proc

exit 0

実行形式にします。

chmod +x chroot.sh

実行します。

# ./chroot.sh
# apt update
# apt upgrade

これでDebianが使えるようになります。

Nginxをインストールする

Debianが使えるようになったところで、Nginxをインストールしてみます。目的はLibreELECをインターネットからアクセス出来るようにするためです。

aptでnginxとcronをインストールします。

/etc/nginx/sites-enabled/example.mydns.net

server { 
    listen       80; 
    server_name   example.mydns.net; 
    return 301    https://$host$request_uri; 
} 
 
server { 
    listen       443 ssl; 
    server_name example.mydns.net;

    proxy_set_header    X-Real-IP       $remote_addr; 
    proxy_set_header    Host            $http_host; 
    proxy_set_header    X-Forwarded-Proto $scheme; 
    proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header    X-Forwarded-Host $http_host; 
    proxy_set_header    X-Forwarded-Server $host; 
 
#    listen 443 ssl; # managed by Certbot 
ssl_certificate /etc/letsencrypt/live/example.mydns.net/fullchain.pem; # managed by Certbot 
ssl_certificate_key /etc/letsencrypt/live/example.mydns.net/privkey.pem; # managed by Certbot 
ssl_session_cache shared:le_nginx_SSL:1m; # managed by Certbot 
ssl_session_timeout 1440m; # managed by Certbot 
 
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # managed by Certbot 
ssl_prefer_server_ciphers on; # managed by Certbot 
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA ECDHE-ECDSA-AES256-SHA ECDHE
-ECDSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-SHA 
ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES256-SHA384 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-SHA DHE-R
SA-AES256-SHA DHE-RSA-AES128-SHA256 DHE-RSA-AES256-SHA256 EDH-RSA-DES-CBC3-SHA"; # managed by Certbot 
 
    location / { 
        return 301 http://$host/emby; 
    } 
    location /emby/ { 
        proxy_pass http://localhost:8096/; 
 
        error_log /var/log/nginx/emby.error; 
        access_log /var/log/nginx/emby.access; 
 
        proxy_read_timeout  240; 
        proxy_buffering off;
        proxy_redirect off; 
    } 
    location /kodi/ { 
        proxy_pass http://localhost:8080/; 
 
        error_log /var/log/nginx/kodi.error; 
        access_log /var/log/nginx/kodi.access; 
 
        proxy_read_timeout 240; 
        proxy_redirect off; 
        proxy_buffering off;  
    }
#   location /plex/ { 
#       proxy_pass http://192.168.1.9:32400/; 
#
#      error_log /var/log/nginx/plex.error; 
#       access_log /var/log/nginx/plex.access; 
#
#       proxy_read_timeout  90; 
#       proxy_redirect default; 
#   } 
    location ~ /.well-known/acme-challenge { 
        allow all; 
    } 
}

Nginxが無事動いたらいったんchroot環境から抜けます。

スクリプトを作成します。

chroot-start-daemon.sh

#!/usr/bin/sh 
 
CHROOT=/storage/srv/chroot/stretch 
PKGS="nginx cron" 
 
mount -o bind /proc $CHROOT/proc 
mount -o bind /sys $CHROOT/sys 
mount -o bind /dev $CHROOT/dev 
mount -o bind /dev/shm $CHROOT/dev/shm 
mount -o bind /dev/pts $CHROOT/dev/pts 
mount -o bind /sys/kernel/debug $CHROOT/sys/kernel/debug 
mount -o bind /sys/kernel/config $CHROOT/sys/kernel/config 
mount -o bind /dev/mqueue $CHROOT/dev/mqueue 
 
sleep 3 
 
for i in $PKGS; do 
    chroot $CHROOT /usr/bin/env -i \ 
        HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \ 
        PATH=/bin:/usr/bin:/sbin:/usr/sbin \  
        /bin/bash /etc/init.d/$i start 
done     
 
exit 0

chroot-stop-daemon.sh

#!/usr/bin/sh 
 
CHROOT=/storage/srv/chroot/stretch 
PKGS="nginx cron" 
 
for i in $PKGS; do 
    chroot $CHROOT /usr/bin/env -i \ 
        HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \ 
        PATH=/bin:/usr/bin:/sbin:/usr/sbin \ 
        /bin/bash /etc/init.d/$i stop 
done 
sleep 3 
 
exit 0

chroot-stop-env.sh

#!/usr/bin/sh 
 
CHROOT=/storage/srv/chroot/stretch 

umount $CHROOT/dev/mqueue 
umount $CHROOT/sys/kernel/config 
umount $CHROOT/sys/kernel/debug 
umount $CHROOT/dev/pts 
umount $CHROOT/dev/shm 
umount $CHROOT/dev 
umount $CHROOT/sys 
umount $CHROOT/proc 
 
exit 0

設定用のディレクトリに移動します。

# cd /storage/.config

autostart.sh

( 
    /storage/chroot-start-daemon.sh 
) &

shutdown.sh

case "$1" in 
  halt) 
    /storage/chroot-stop-daemon.sh 
    ;; 
  poweroff) 
    /storage/chroot-stop-daemon.sh 
    ;; 
  reboot) 
    /storage/chroot-stop-daemon.sh      
;; 
  *) 
    /storage/chroot-stop-daemon.sh 
    ;; 
esac

Armbianを使う方法

Armbianを使う場合はすこし簡単です。イメージファイルを次のサイトからダウンロードします。

https://yadi.sk/d/pHxaRAs-tZiei

イメージのファイルを調べます。

file Armbian_5.34_S9xxx_Debian_stretch_3.14.29_server_20171104.img

Armbian_5.34_S9xxx_Debian_stretch_3.14.29_server_20171104.img: DOS/MBR boot sector; partition 1 : ID=0xe, start-CHS (0x40,0,1), end-CHS (0x3ff,3,32), startsector 8192, 262144 sectors; partition 2 : ID=0x83, start-CHS (0x3ff,3,32), end-CHS (0x3ff,3,32), startsector 270336, 3563520 sectors

HDDイメージであることが分かります。さらにfdiskを使ってみます。

fdisk Armbian_5.34_S9xxx_Debian_stretch_3.14.29_server_20171104.img

Command (m for help): p

Disk Armbian_5.34_S9xxx_Debian_stretch_3.14.29_server_20171104.img: 1.8 GiB, 1962934272 bytes, 3833856 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: 0x1a9b4ccd

Device                                                         Boot  Start     End Sectors  Size Id Type
 Armbian_5.34_S9xxx_Debian_stretch_3.14.29_server_20171104.img1        8192  270335 262144  128M  e W95 FAT16 (LBA)
 Armbian_5.34_S9xxx_Debian_stretch_3.14.29_server_20171104.img2      270336 3833855 3563520  1.7G 83 Linux

Command (m for help): q

イメージファイルの始まりが270336で終わりが3833855なので、これの情報を元にイメージを切り取ります。

$ dd if=Armbian_5.34_S9xxx_Debian_stretch_3.14.29_server_20171104.img of=Armbian_5.34_roofs.img skip=270336 bs=512

マウントしてエラーがでなければ正しく切り取れています。

$ sudo mount Armbian_5.34_roofs.img mnt

この新しいイメージファイルをLibreELECに移します。

# mkdir -p srv/chroot/armbian
# mkdir -p srv/chroot/armbian
# mount -o loop Armbian_5.34_rootfs.img ./srv/chroot/armbian
# mount -o loop Armbian_5.34_rootfs.img ./srv/chroot/armbian

これでマウント出来ました。

あとは同じようにchrootするだけです。

chroot環境ではsystemdが使えません。そのためcgroupと整合性がとれずシステムが若干不安定になるかも知れません。

追記:それでもDockerを使いたい

カーネルがoverlayfsに対応していないのでDockerが起動に失敗するのですが、やはり使ってみたいという場合、方法がないわけではありません。Dockerのファイルシステムを無視して上層レイヤに下層レイヤの情報をコピーするだけです。起動してみます。

# docker start mydebian
# docker attach mydebian
root@421c2c3c636e:/# ls 
bin  boot  dev  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

References:

(旧)Roundcube + Nginxをインストールする

次の記事に集約しました。

・Mail Server: PostfixとDovecotを使ったメールサーバの構築

 


メールのサーバ証明書が切れたのでLets encryptを使うことにしました。Lets encryptはWeb向けに作られていて、証明書はメールサーバにも使えるのですがWebサーバがないと取得が出来ません。そこでWebmailを更新と同時に証明書も刷新することにしました。

以前、PostfixとDovecotを使ったメールサーバを構築しましたがどうもWebmailの調子が良くありません。そこでWebmailアプリのRoundcubeをインストールしてみました。

VPSサーバの下にUbuntuのlxcのメールサーバがあります。そこにnginxのWebサーバがインストールされてあり、そこにRoundcubeをインストールします。aptで関連モジュール一式をインストールしましたがどうもうまく行きません。そこでRoundcubeのサイトからパッケージをダウンロードしてインストールしました。

Let’s encrypt

1台のVPSで運用して複数ドメインを使ってみます。たとえばwww.example.comとmail.example.comような感じです。wordpress用とメール用の共通の証明書を作ります。

$ sudo certbot --manual

質問に答えて割符が合えば証明書のインストールができます。定期的にアップデートする必要があるのでcronに登録しておきます。アップデートは次のようにします。

/usr/bin/certbot renew -d <Domain 1> -d <Domain 2>

NginxのReverse Proxyを使っている場合、そのプロキシサーバに証明書をインストールします。その証明書はメールサーバにrsync等でコピーします。

Roundcube + Nginx

NginxのWebサーバにPHP7.0が稼働しているのが条件です。Roundcubeはapache向けに作られているので作業は少し煩雑になります。

Roundcubeのインストール場所は/usr/shareです。roundcubemail-1.2.9を展開しroundcubemailにシンボリックリンクを張ります。roundcubemail-1.2.9以下ユーザ/グループをwww-dataに変えます。関連パッケージはサイトを見てインストールしていきます。例えばPEARパッケージはaptでインストールしない時があるのでインストールします。

PHP version 5.4.1 or greater with

  • PCRE (Perl-Compatible Regular Expressions)
  • DOM
  • JSON
  • XML
  • Mbstring
  • OpenSSL
  • Session support
  • Socket support
  • PHP Data Objects (PDO) with driver for either MySQL, PostgreSQL, SQL Server or SQLite
  • Iconv (optional)
  • FileInfo (optional)
  • Zip (optional)
  • Pspell (optional)

PEAR packages distributed with Roundcube or external:

  • Mail_Mime 1.10.0 or newer
  • Net_SMTP 1.7.1 or newer
  • Net_Socket 1.2.1 or newer
  • Net_IDNA2 0.1.1 or newer
  • Auth_SASL 1.1.0 or newer
  • Net_Sieve 1.4.0 or newer (for managesieve plugin)
  • Crypt_GPG 1.6.1 or newer (for enigma plugin)
  • Net_LDAP2 2.2.0 or newer (for LDAP address books)
  • kolab/Net_LDAP3 dev-master (for LDAP address books)

例)

$ sudo pear install Mail_Mime

PHPの例)

$ sudo apt install php-pear php-mysql php-mcrypt php-intl

データベースを作成します。SQLサーバ(MySQL)は違うホストある場合のインストール方法です。

$ mysql -u root -p

mysql> CREATE DATABASE roundcubemail;
mysql> GRANT ALL PRIVILEGES ON roundcubemail.* TO 'roundcube'@'<IP>' IDENTIFIED BY 'password';
mysql> GRANT ALL PRIVILEGES ON client_data.* to 'roundcube'@'<IP>' identified by 'password' with grant option; mysql> FLUSH PRIVILEGES; 
mysql> quit 

$ mysql -u roundcube -h <IP> -p roundcubemail < /usr/share/webapps/roundcubemail/SQL/mysql.initial.sql

ネットワーク経由でアクセスする場合は設定を変更します。

my.cnf

bind-address            = 0.0.0.0

 

ディレクトリの作成とパーミッションの変更

$ sudo chmod 775 /var/cache/roundcube
$ sudo chown www-data:www-data /var/cache/roundcube
$ sudo mkdir /var/log/roundcubemail
$ sudo chmod 775 /var/log/roundcubemail
$ sudo chown www-data:www-data /var/log/roundcubemail
$ sudo mkdir -p /var/lib/roundcubemail/temp
$ sudo chmod 775 /var/lib/roundcubemail/temp
$ sudo chown www-data:www-data /var/lib/roundcubemail/temp

 

Nignxの設定

ArchLinuxのサイトを参考に作成してみました。

server { 
    listen 443 ssl; 
    server_name mail.example.com; 
    root /var/www/html; 
    #index index.php index.html index.htm; 
    port_in_redirect on; 
    location = /50x.html { 
        root /usr/share/nginx/html; 
    } 
    error_page 404 /404.html; 
    error_page 500 502 503 504 /50x.html; 
    location / { 
        rewrite ^.*$ https://mail.example.com/webmail permanent; 
    } 
    location /webmail { 
        alias /usr/share/roundcubemail; 
        index index.php; 
        error_log /var/log/nginx/roundcubemail.error; 
        access_log /var/log/nginx/roundcubemail.access; 
        # Favicon 
        location ~ ^/webmail/favicon.ico$ { 
            root /usr/share/roundcubemail/skins/classic/images; 
            log_not_found off; 
            access_log off; 
            expires max; 
        } 
        # Robots file 
        location ~ ^/webmail/robots.txt { 
            allow all; 
            log_not_found off; 
            access_log off; 
        } 
        # Deny Protected directories  
            location ~ ^/webmail/(config|temp|logs)/ { 
            deny all; 
        } 
        location ~ ^/webmail/(README|INSTALL|LICENSE|CHANGELOG|UPGRADING)$ { 
            deny all; 
        } 
        location ~ ^/webmail/(bin|SQL)/ { 
            deny all; 
        } 
        # Hide .md files
        location ~ ^/webmail/(.+\.md)$ {
            deny all;
        }
        location ~ ^/webmail/(.+\.php)$ { 
            fastcgi_pass unix:/run/php/php7.0-fpm.sock; 
            fastcgi_index index.php; 
            fastcgi_split_path_info ^/webmail(.+\.php)(/.*)$; 
            #fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 
            fastcgi_param SCRIPT_FILENAME $request_filename; 
            fastcgi_param PHP_VALUE    open_basedir="/tmp/:/var/cache/roundcubemail:/usr/share/roundcubemail:/etc/roundcubemail:/var/lib/roundcubemail/temp:/var/log/roundcubemail:/usr/share/php"; 
            include fastcgi_params; 
        } 
    } 
#    listen 443 ssl; # managed by Certbot 
ssl_certificate /etc/letsencrypt/live/mail.example.com/fullchain.pem; # managed by Certbot 
ssl_certificate_key /etc/letsencrypt/live/mail.example.com/privkey.pem; # managed by Certbot 
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot 
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot 
 
    location ~ /.well-known/acme-challenge { 
        allow all; 
    } 
}

 

<サイト>/installerにアクセスしてRoundcubeの設定をします。SSL/TLSおよびSTARTTLSの設定は次のようになります。

$config['default_host'] = 'ssl://mail.example.com';
$config['default_port'] = 993
$config['smtp_server'] = 'tls://mail.example.com';
$config['smtp_port'] = 587;
$config['smtp_user'] = '%u';
$config['smtp_pass'] = '%p';

 

Roundcubeがメール−サーバと同じプライベートネットワークにあるとき起こる問題

データーベースの設定をすれば繋がるはずですが、テストするとどうもメールサーバにつながりません。メールサーバの設定を全部見直してみましたが問題ありません。どうもNATの問題があるようです。次のようにテストしてみました。

$ sudo openssl s_client -connect mail.example.com:587 -starttls smtp
 connect: Connection refused
 connect:errno=111

 

x509で認証するためグローバルアドレスでアクセスしますが、ポートフォワーディングしてるとローカルネットからつながりません。かといってローカルアドレスでアクセスすれば認証できません。検索しても回答が見つかりませんでしたが、次のようにhostsにローカルアドレスを追加したらうまく接続できました。

/etc/hosts

192.168.20.1 mail.example.com

 

Fail2ban

Fail2banはアクセス制限をしてくれるアプリです。サーバごとにそれぞれ設定します。ログを解析してアクセス制限するのでパスを摺り合わせます。

/etc/fail2ban/jail.d

defaults-debian.conf  dovecot.conf  nginx-http-auth.conf  php-url-fopen.conf  postfix.conf  roundcube-auth.conf

 

記述例)

grep roundcube_errors_log paths-common.conf
paths-common.conf:roundcube_errors_log = /var/log/roundcubemail/errors

roundcube-auth.conf

[roundcube-auth] 
enableed = true 
port     = http,https 
logpath = %(roundcube_errors_log)s

稼働状況

$ sudo fail2ban-client status
Status 
|- Number of jail:      5 
`- Jail list:   dovecot, php-url-fopen, postfix, roundcube-auth, sshd

エラーが発生た時の対処法

systemd[1]: fail2ban.service: Start request repeated too quickly.

クライアントを実行して原因を調べます。

$ sudo fail2ban-client -vvv -x start

 

IKEv2およびOpenVPNの鍵と証明書の管理方法

今までにstrongSwan、OpenVPN、WI-FiのWPA2で鍵と証明書を作っていましたが、段々と管理が雑然としてしてきました。いくつか作っては放置したままになっていたり、うっかり消して作りなおしたりしてあまり安全性の面では良くありません。そこで管理アプリとして前にネットで見かけたLinux版XCAというアプリを使ってみました。

データベースを簡単に作れるので各サーバごとに分けたほうが管理が良さそうです。

OpenVPNを例に作成してみます。

まず最初にCAの鍵と証明書をインポートします。次に最初に作ったClientの鍵と証明書をインポートします。

この情報を元にClientの鍵と証明書をXCAで量産することが出来ます。テンプレートを作ります。

同じ場所から右クリックしてNEWを選択します。

Source:

  • Signing: Use this Certificate for signing
  • Template for the new certificate: 新しく作ったテンプレート  –> Apply all

Subject:

  • Internal name: 新しいユーザ名
  • commonName: 新しいユーザ名
  • Privcate key: Used keys tooをチェックしてGenerate a new keyで作成(例:RSA/4096 bit)

OKボタンを押します。

これでClientの鍵と証明書は完成です。

次にエキスポートします。

Certificate: Exportボタンを押して、ディレクトリを指定しそのままOKボタンを押してエキスポートします。

CA証明書を同様にエキスポートします。

秘密鍵はOpenVPNに合わせてPKCS#8フォーマットでエキスポートします。

 

OpenVPNをセットアップする

IKEv2のstrongSwanはすでに構築してあるので今更OpenVPNを構築する意味はありませんが、SSLを利用したVPNでシンプルという理由で構築することにしました。

メリットはファイヤーウォールを通すのがIKEv2に比べてとても楽なことです。またコマンドラインから簡単に起動できます。

デビアン系ではapt install openvpnでインストールします。OpenWrtはopkg install openvpn-openssl(またはopenvpn-mbedtls)としてインストールします。

構築手順

  1. 同じセグメントで共通鍵でセットアップ
  2. nat越しで共通鍵でセットアップ
  3. TLS/SSLでセットアップ

いきなりインタネット越しにTLSでセットアップしても良いのですがエラーがある場合に問題の切り出しが面倒なのでシンプルな方法から始めます。

1. 同じセグメントで共通鍵でセットアップ

VPNのセットアップではファイヤーウォールで躓くことが多いので、単純なネットワーク構成で設定ファイルのテンプレートを作ります。

共通鍵を作成

$ sudo openvpn --genkey --secret static.key

static.keyをscp等でサーバー側にもコピーします。

Serverの設定

server.conf:

proto udp 
dev tun 
port 1194 
# サーバのアドレスが10.8.0.1、クライアントが10.8.0.2です
ifconfig 10.8.0.1 10.8.0.2 
secret /tmp/static.key 
comp-lzo 
keepalive 10 60 
ping-timer-rem 
persist-tun 
persist-key 
route 10.8.0.0 255.255.255.0
verb 5

Clientの設定

client.conf:

サーバ、クライアントの起動

$ sudo openvpn --config client.conf

サーバのOpenWrtでは次のようなエラーがでましたが接続はできました。

write to TUN/TAP : Invalid argument (code=22)

2. nat越しで共通鍵でセットアップ

同じようにサーバに共通鍵をコピーします。

Serverの設定

proto udp 
dev tun 
port 1194 
ifconfig 10.8.0.1 10.8.0.2 
secret static.key 
comp-lzo  
keepalive 10 60 
ping-timer-rem 
persist-tun 
persist-key 
route 10.8.0.0 255.255.255.0

Clientの設定

remote <VPS等のIPまたはFQDN>
proto udp 
dev tun 
port 1194 
ifconfig 10.8.0.2 10.8.0.1 
static.key 
comp-lzo 
keepalive 10 60 
ping-timer-rem 
persist-tun 
persist-key 
route 10.8.0.0 255.255.255.0

ファイヤーウォール(FW)の設定

サーバ側

  • Port 1194を開ける
  • VPN用のゾーンを作る
  • VPNからネットへアプセスを許可する
  • VPNからFWへアクセスを許可する
  • FWからVPNにアクセスを許可する

クライアント側

  • IPマスカレードする

または

  • またはポートをのみマスカレードする

例)

$ sudo iptables -t nat -A POSTROUTING -o  $INETIF -p udp --dport 1194 -j MASQUERADE

サーバの場合、1194 udp をポートフォワーディングする。

3. TLS/SSLでセットアップ

OpenSSLを使って鍵と証明書を作成します。

$ sudo mkdir -m 700 /root/certs
$ sudo touch /root/certs/index.txt
$ sudo touch /root/certs/index.txt.attr
$ sudo echo "01" > /root/certs/serial

/etc/ssl/openssl.cnfを編集します。

#
# OpenSSL configuration based on sample configuration shipped 
# with OpenVPN. 
# 
 
############################################################# 
# modify according to your needs 
 
KEY_SIZE               = 4096 
KEY_COUNTRY            = JP 
KEY_PROVINCE           = SA 
KEY_CITY               = NOWHERE 
KEY_ORG                = MYEXAMPLE.COM 
KEY_ORGUNIT            = IT-DIVISION 
KEY_EMAIL              = root@server.myvpn.com 
HOME                   = /root 
KEY_DIR                = $ENV::HOME/certs 
RANDFILE               = $ENV::HOME/.rnd 
 
############################################################# 
 
openssl_conf           = openssl_init 
 
[ openssl_init ] 
 
oid_section            = new_oids 
engines                = engine_section 
 
[ new_oids ] 
 
[ engine_section ] 
 
[ ca ] 
 
default_ca             = CA_default 
 
[ CA_default ] 
 
dir                    = $ENV::KEY_DIR 
certs                  = $dir 
crl_dir                = $dir 
database               = $dir/index.txt 
new_certs_dir          = $dir 
certificate            = $dir/vpn_ca.crt 
serial                 = $dir/serial 
crl                    = $dir/crl.pem 
private_key            = $dir/vpn_ca.key 
RANDFILE               = $dir/.rand 
x509_extensions        = usr_cert 
default_days           = 3650 
default_crl_days       = 30 
# IMPORTANT: The next must no longer be md5, if used with 
# Debian's OpenLDAP package being compiled against libgnutls. 
default_md             = sha1 
preserve               = no 
policy                 = policy_match 
 
 
[ policy_match ] 
 
countryName            = match 
stateOrProvinceName    = match 
organizationName       = match 
organizationalUnitName = optional 
commonName             = supplied 
emailAddress           = optional 
 
[ policy_anything ] 
 
countryName            = optional 
stateOrProvinceName    = optional 
localityName           = optional 
organizationName       = optional 
organizationalUnitName = optional 
commonName             = supplied 
emailAddress           = optional 
 
[ req ] 
 
default_bits           = $ENV::KEY_SIZE 
default_keyfile        = privkey.pem 
distinguished_name     = req_distinguished_name 
attributes             = req_attributes 
x509_extensions        = v3_ca 
string_mask            = nombstr 
 
[ req_distinguished_name ] 
 
countryName            = Country Name (2 letter code) 
countryName_default    = $ENV::KEY_COUNTRY 
countryName_min        = 2 
countryName_max        = 2 
 
stateOrProvinceName    = State or Province Name (full name) 
stateOrProvinceName_default = $ENV::KEY_PROVINCE 
 
localityName           = Locality Name (eg, city) 
localityName_default   = $ENV::KEY_CITY 
 
0.organizationName     = Organization Name (eg, company) 
0.organizationName_default = $ENV::KEY_ORG 
 
organizationalUnitName = Organizational Unit Name (eg, section) 
organizationalUnitName_default = $ENV::KEY_ORGUNIT 
 
commonName             = Common Name (eg, your name or your server\'s hostname) 
commonName_max         = 64 
 
emailAddress           = Email Address 
emailAddress_default   = $ENV::KEY_EMAIL 
emailAddress_max       = 40 
 
[ req_attributes ] 
 
challengePassword      = A challenge password 
challengePassword_min  = 4 
challengePassword_max  = 20 
unstructuredName       = An optional company name 
 
[ usr_cert ] 
 
basicConstraints       = CA:FALSE 
nsComment              = "OpenSSL Generated Certificate" 
subjectKeyIdentifier   = hash 
authorityKeyIdentifier = keyid,issuer:always 
extendedKeyUsage       = clientAuth 
keyUsage               = digitalSignature 
 
[ server ] 
 
basicConstraints       = CA:FALSE 
nsCertType             = server 
nsComment              = "OpenSSL Generated Server Certificate" 
subjectKeyIdentifier   = hash 
authorityKeyIdentifier = keyid,issuer:always 
extendedKeyUsage       = serverAuth 
keyUsage               = digitalSignature, keyEncipherment 
 
[ v3_req ] 
 
basicConstraints       = CA:FALSE 
keyUsage               = nonRepudiation,digitalSignature,keyEncipherment 
 
[ v3_ca ] 
 
subjectKeyIdentifier   = hash 
authorityKeyIdentifier = keyid:always,issuer:always 
basicConstraints       = CA:true 
 
[ crl_ext ] 
 
authorityKeyIdentifier = keyid:always,issuer:always

CA証明書の作成

$ sudo cd /root/certs
$ sudo openssl req -nodes -new -x509 -keyout vpn_ca.key -out vpn_ca.crt
...
Common Name (eg, your name or your server's hostname) []:
...

サーバの鍵と証明書の作成

$ sudo cd /root/certs
$ sudo openssl req -nodes -new -extensions server \
  -keyout vpn_server.key -out vpn_server.csr
...
Common Name (eg, your name or your server's hostname) []:
...

$ sudo openssl ca -extensions server \
  -out vpn_server.crt -in vpn_server.csr
...
Sign the certificate? [y/n]:y 
 
 
1 out of 1 certificate requests certified, commit? [y/n]y 
Write out database with 1 new entries 
Data Base Updated

クライアントの鍵と証明書の作成

$ sudo openssl req -days 1095 -new -keyout vpn_client.key -out vpn_client.csr     
Generating a 4096 bit RSA private key 
...................................................................++ 
..............................................................++ 
writing new private key to 'client.key' 
Enter PEM pass phrase: 
Verifying - Enter PEM pass phrase:
...
Common Name (eg, your name or your server's hostname) []:
...
openssl ca -days 1095 -out vpn_client.crt -in vpn_client.csr

Common Nameはユーザごとユニークな名前にします。

Diffie-Hellman(DH)鍵の作成

$ sudo openssl dhparam -out dh4096.pem 4096
または
$ sudo sudo openssl dhparam -dhparam -out dh4096.pem 4096

TLS認証鍵作成

$ sudo openvpn --genkey --secret ta.key
$ sudo cp ta.key /etc/openvpn

この同じキーをClient側にもインストールします。

所定の場所に鍵と証明書をコピーします。

$ sudo cp vpn_ca.crt vpn_server.crt /etc/ssl/certs
$ sudo cp dh4096.pem vpn_server.key /etc/ssl/private
$ sudo chown root:ssl-cert /etc/ssl/private/vpn_server.key /etc/ssl/private/dh4096.pem
$ sudo chmod 600 /etc/ssl/private/vpn_server.key
$ sudo chmod 640 /etc/ssl/private/dh4096.pem

設定ファイルのServer用テンプレートをコピーします。

$ sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn
$ sudo gunzip /etc/openvpn/server.conf.gz

/etc/openvpn/server.conf:

port 1194 
proto udp 
dev tun 
ca /etc/ssl/certs/vpn_ca.crt 
cert /etc/ssl/certs/vpn_server.crt 
key /etc/ssl/private/vpn_server.key  # This file should be kept secret 
#crl-verify /etc/ssl/certs/crl.pem
dh /etc/ssl/private/dh4096.pem 
server 10.8.0.0 255.255.255.0 
ifconfig-pool-persist ipp.txt 
keepalive 10 60 
tls-auth ta.key 0 # This file is secret 
cipher AES-256-CBC 
comp-lzo 
user nobody 
group nogroup 
persist-key 
persist-tun 
status openvpn-status.log 
verb 3 
explicit-exit-notify 1

起動テスト

$ sudo openvpn --config server.conf

すべてのClient側のトラフィックをサーバ経由にする場合に追加します。

push "redirect-gateway def1 bypass-dhcp"

サーバの自動設定

/etc/default/openvpn:

AUTOSTART="all"
$ sudo systemctl enable openvpn
$ sudo systemctl start openvpn

サーバで作ったClient用の鍵と証明書をClient側にコピーしてOpenVPNの設定ディレクトリに移動します。

$ sudo mv ta.key vpn_ca.crt vpn_client.crt vpn_client.key /etc/openvpn

/usr/share/doc/openvpn/examples/sample-config-filesからClient用の設定をコピーし編集します。

/etc/openvpn/client.conf:

client 
dev tun 
proto udp 
remote <server> 1194 
resolv-retry infinite 
nobind 
user nobody 
group nogroup 
persist-key 
persist-tun 
ca /etc/openvpn/vpn_ca.crt 
cert/etc/openvpn/vpn_client.crt 
key/etc/openvpn/vpn_client.key 
remote-cert-tls server 
tls-auth ta.key 1 
cipher AES-256-CBC 
comp-lzo 
verb 3

起動テスト

$ sudo openvpn --config client.conf

Network Managerを使えばより便利になります。

Revocation Listの設定

Clientの証明書を無効にする場合、Revocationを行います。

例)RevocationされるとindexがRに変わります。

$ sudo cd /root/certs
$ sudo grep libreelec *.pem
04.pem:        Subject: C=JP, ST=SA, O=MYEXAMPLE.COM, OU=IT-DIVISION, CN=libreelec/emailAddress=root@server.
vpn.com
 
$ sudo cat index.txt 
R       201115165255Z   171116165340Z   04      unknown /C=JP/ST=SA/O=MYEXAMPLE.COM/OU=IT-DIVISION/CN=libree
lec/emailAddress=root@server.vpn.com

$ sudo openssl ca -revoke 04.pem
$ sudo openssl ca -gencrl -out crl.pem
$ sudo cp crl.pem /etc/ssl/certs/

サーバーの設定ファイルに追加します。

$ sudo crl-verify /etc/ssl/certs/crl.pem

RevocationされたClientがアクセスしようとすると拒否されます。

$ sudo journalctl -xf
...
OpenSSL: error:14089086:SSL routines:ssl3_get_client_certificate:certificate verify failed

Troubleshoot

鍵と証明書の作成で次のようなエラーが出た場合

failed to update database
 TXT_DB error number 2

次のようにリボーケーションしてデータベースを更新します。

$ sudo openssl ca -revoke 01.pem

追記:OpenWrtの設定

OpenWrtは独特なエコシステムなのでダッシュボードでFirewallとNetwork関係を設定します。まずOpenVPNのポート開放します。

次にインターフェースの設定を行います。Tun0デバイスを選択します。Tun+みたいな使い方はちょっと分かりません。

最後にfirewallの設定をします。ゾーンを作成してOpenVpn->Lan、Wanにフォワーディングを出来るようにします。またインターフェースのopenvpnとのリンクもします。

以上で完了です。

追記2:ovpnファイルの作成

ちょっと手間がかかるのでシェルスクリプトで対応しました。スクリプトで作成して余計な部分はエディタで修正します。

mk_ovpn.conf

output='client.ovpn'
server='tset.mydns.jp'
client_conf='client.conf'
cacert_file='test_openvpn_ca.crt'
cert_file='test@openvpn.crt'
key_file='test@openvpn.pem'
ta_key='ta.key

mk_ovpn.sh

#!/bin/bash

. ./mk_ovpn.conf

echo "client" > $output
echo "remote $server" >> $output
[ -f $client_conf ] && cat $client_conf >> $output
sed -i '/^#/d' $output
sed -i '/^;/d' $output
sed -i '/^$/d' $output
sed -i '/ca\s*/d' $output
sed -i '/cert\s*/d' $output
sed -i '/key\s*/d' $output
sed -i '/tls-auth\s*/d' $output
echo -e "\nkey-direction 1\n" >> $output
echo "<ca>" >> $output
[ -f $cacert_file ] && cat $cacert_file >> $output
echo -e "</ca>\n" >> $output
echo "<cert>" >> $output
[ -f $cert_file ] && cat $cert_file >> $output
echo -e "</cert>\n" >> $output
echo "<key>" >> $output
[ -f $key_file ] && cat $key_file >> $output
echo -e "</key>\n" >> $output
echo "<tls-auth>" >> $output
[ -f $ta_key ] && cat $ta_key >> $output
echo -e "</tls-auth>\n" >> $output

References

IEEE 802.11s Meshネットワーク+tinc VPNをセットアップする

UPDATE:18 JAN 2019

OpenWRT 18.06.1では”wpad-mesh-openssl – Supplicant (with 802.11s mesh and SAE support)”というパッケージがありSAEサポートのあるWIFIだと使えるらしいです。私の機種は古いので使えませんでした。ということでTincをアップデートしました。遅いですが安定しています。(1MB/s)

ずい分前に802.11sのmeshネットワークのセットアップの記事を書きましたが、セキュリティがないため使えませんでした。ところが先日LibreELECのtinc VPNをセットアップして、すこし調べていたらスイッチモードでVPNを構築できることが分かりました。どういうことかというとLANのハブみたいにネットワーク同士を同じセグメントで繋ぐことが出来ます。meshネットワークととても相性が良くtinc VPNを組み合わせればセキュアなmeshネットワークが出来上がります。

次の図は構築イメージです。

ネットワーク図

tinc VPN (Network A + B + C: 192.168.1.0/24)
+---------------------------------------------+
|  +---------------+      Mesh Network        |
|  | Network A     |      10.0.0.0/16         |  Network A: Router A
|  |192.168.1.1/24 |                          |  Network B: Router B
|  +---------------+      +---------------+   |  Network C: Router C
|                         | Network C     |   |
|  +---------------+      |192.168.1.3/24 |   |
|  | Network B     |      +---------------+   |
|  |192.168.1.2/24 |                          |
|  +---------------+                          |
+---------------------------------------------+

構築手順

  1. Meshネットワークの設定
  2. インターフェースの設定
  3. Firewallの設定
  4. Dropbearの設定
  5. tincのインストール
  6. ダッシュボードの設定
  7. tincの設定
  8. ポストインストレーション

今回、使用したルーター、FirmwareはOprnWRT 15.05

  • Buffalo WZR-HP-G300NH2 x1
  • Buffalo WZR-HP-AG300H x2

1.Meshネットワークの設定

Mesh対応のWi-Fiアダプターはiw listを使って調べます。mesh pointがあれば対応しています。

/etc/config/wireless:

config wifi-iface 
        option device 'radio0' 
        option mode 'mesh' 
        option mesh_id 'mesh' 
        option encryption 'none' 
        option network '80211s'

Meshネットワーク用のIPアドレスを設定します。

/etc/config/network:

config interface '80211s' 
        option proto 'static' 
        option ipaddr '10.0.0.1' 
        option netmask '255.255.0.0'

2台のルータのIPアドレスは例として10.0.0.1と10.0.0.2として設定しています。設定が済んだらWi-Fiとネットワークを再起動します。

wifi
/etc/init.d/network restart

Meshネットワークが動作しているか以下のようにテストしてみます。

iw dev wlan0 station dump

-- stationリストの出力 ---

stationリストが出力されたらMeshネットワークが機能しています。つぎにIPアドレスを割り当ててssh等でアクセスしてみます。接続できれば次のコマンド打ってみます。

iw dev wlan0 mpath dump 
 
DEST ADDR         NEXT HOP          IFACE       SN      METRIC  QLEN    EXPTIME         DTIM    DRET    FL$ 
a0:b5:35:2c:f0:1b c0:d3:65:8a:c3:6f wlan0       2       106     0       0       0       0       0x14

このようにHWアドレスのリンク情報が得られます。手動で行う場合は次のようにします。

iw dev wlan0 interface add mesh type mp mesh_id mesh

または

iw phy phy0 interface add mesh type mp mesh_id mesh

チャンネルはデフォルトで1ですが変更する場合はセットします。

iw dev mesh set channel 6
ifconfig wlan0 down
ifconfig mesh up
ifconfig mesh 10.0.0.1/16

2. インターフェースの設定

OpenWRTのダッシュボードNetwork>Interfacesでインターフェースを作ります。

今回は80211sというインターフェースを作ります。1.Meshネットワークの設定ですでに出来上がっているはずです。Physical SettingsWireless NetworkMeshにリンクしていることを確認します。

3. Firewallの設定

オープンなネットワークなのでダッシュボードでFirewallの設定をします。基本的にWANと同じ設定です。WANの設定を使ってもいいのですが、今回はメッシュ専用の80211sのZoneを作成します。

Advanced SettingsForce connection trackingをオンにします。

保存して/etc/init.d/firewall restartで再起動します。

つぎに必要最小限のポート開放します。今回はping、tincで使う655ポート、そしてssh用の2222ポートです。sshはデフォルトの22ポートでもいいのですが、変更を加えた時にアクセス不能になった場合、修復が大変なのでポートを追加することをおすすめします。

設定が済んだらfirewallを再起動します。

4. Dropbearの設定

/etc/config/dropbearを編集します。RSAキーによるアクセス設定にします。

config dropbear 
        option PasswordAuth 'on' 
        option Port '22' 
        option Interface 'lan' 
 
config dropbear 
        option PasswordAuth 'off' 
        option Port '2222'

次に各ルータにRSAキーが必要なので、RSAキーがない場合には作成します。RSAキーは/root/.sshに作成します。

ssh-keygen -b 4096

各ルータに公開鍵を登録します。

nano /etc/dropbear/authorized_keys

dropbearを再起動してテストして見ます。

ssh -p2222 root@10.0.0.2

5. tincのインストール

sshでmeshネットワークからアクセスします。

例)

ssh -p2222 root@10.0.0.2

接続できること確認したらルータ同士をつないでいるLANケーブルを抜きます。tincをセットアップしてIPパケットが輻輳するのを防ぐ措置です。

パッケージインストールプログラムのopkgでtincをインストールします。

opkg update
opkg install tinc

/etc/config/tincを編集します。

config tinc-net myvpn 
        option enabled 1 
 
        ## Daemon Configuration (cmd arguments) 
        option generate_keys 1 
        option key_size 4096 
        option logfile /tmp/log/tinc.NETNAME.log 
        option debug 3 
  
        ## Server Configuration (tinc.conf) 

        option AddressFamily ipv4 

        list ConnectTo node_2
        list ConnectTo node_3

        option Mode switch 
        option Name node_1 
 
 config tinc-host node_1 
        option enabled 1 
        option net myvpn 
        list Address 10.0.0.1 
        option Port 655
        option PMTU 1472

tinc VPNを起動します。

/etc/init.d/tinc start

RSA鍵を作成した後、tincが起動します。

起動用設定ファイルは/var/tinc以下に出来ます。またデバッグをオンにしてあるので接続状況を確認できます。

各ルータの自分以外の/var/tinc/myvpn/hosts以下の情報を/etc/tinc/myvpn/hostsにコピーします。

tincを再起動します。

次にダッシュボードのInterfacesLAN(br-lan)を編集してVPNアダプタをブリッジします。

 

ターミナルから確認してみます。

brctl show 
bridge name     bridge id               STP enabled     interfaces 
br-lan          7fff.b0c7456ed04e       no              eth0.1 
                                                        wlan0-1 
                                                        myvpn

pingを使って相互に接続を確認してみます。

ping 192.168.1.1
...

ping 192.168.1.2
...

6. ポストインストレーション

デバッグのログが溢れるとシステムが止まるので抑制します。

/etc/config/tincを編集してコメントアウトします。

#       option logfile /tmp/log/tinc.NETNAME.log 
#       option debug 3

保存して再起動します。

Nodeを調べる

psでPIDを調べます。

kill -USR2 <PID>
logread

問題点

  • ネットワークが遅い

スループットが大体600~700kb/sくらいしかありません。ダッシュボードのAssociated Stationsを見るとmeshネットワークの速度は130.0 Mbit/sでてるので、単純に計算して16Mb/sくらいでそうですが、やはりSSL接続のオーバヘッドでしょうか。大きなファイルの移動は有線LANを使うしかありません。

  • メッシュノードの追加が煩雑

3台のルータで運用していますが、試しにトラベルルータをmeshネットワークに追加してみました。

hostsの情報を各ルータから取りせるのと、トラベルルータのhosts情報を各ルータに送らなければなりません。台数が増えれば煩雑さは増えていきます。ssh用の公開鍵も追加しなければなりません。

設定例

/etc/config/wireless

config wifi-device 'radio0'
        option type 'mac80211'
        option hwmode '11g'
        option path 'pci0000:00/0000:00:11.0'
        option legacy_rates '1'
        option country 'JP'
        option channel '11'
        option htmode 'HT40'

config wifi-device 'radio1'
        option type 'mac80211'
        option hwmode '11a'
        option path 'pci0000:00/0000:00:12.0'
        option channel 'auto'
        option htmode 'HT40'
        option country 'JP'
        option legacy_rates '1'

config wifi-iface 'default_radio1'
        option device 'radio1'
        option mode 'ap'
        option network 'lan'
        option ssid 'MyPlace'
        option encryption 'wpa2+ccmp'
        option auth_server '10.0.0.1'
        option auth_secret '*password*'
        option disabled '1'

config wifi-iface 'mesh0'
        option device 'radio0'
        option encryption 'none'
        option ifname 'mesh0'
        option mode 'mesh'
        option mesh_fwding '1'
        option network '80211s'
        option mesh_id 'mesh'

Referrences

LibreELEC: tinc addonをセットアップする

s905xで使えるVPNを調べてみましたがカーネルモジュールがないのでIKEv2は使えそうもありません。使えそうなVPNはOpenVPNあたりだと思いますが、LibreELECではtinc addonがあったので設定してみることにしました。

設定は次の画面のように設定しました。

設定ファイルは/storage/.kodi/userdata/addon_data/service.system.tinc/.configにあります。LibreELECはsshが使えうように設定しターミナルからログイン(root/libreelec)します。

hostsにクライアント情報を追加します。

hosts/linux:

Subnet = 192.168.123.2/32 
-----BEGIN RSA PUBLIC KEY----- 

-----END RSA PUBLIC KEY-----

tincを再起動します。

systemctl restart service.system.tinc

ifconfigで次のようになっているはずです。

vmnetz    Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00   
          inet addr:192.168.123.254  P-t-P:192.168.123.254  Mask:255.255.255.0 
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1 
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0 
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 
          collisions:0 txqueuelen:500  
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Client側の設定はLinuxの場合は/etc/tincにあります。

mkdir vmnetz
cd vmnetz

tinc.conf:

cat tinc.conf
 Name = linux
 ConnectTo = libreelec
 port = 6555

tinc-up:

#!/bin/sh
ifconfig $INTERFACE 192.168.123.2 netmask 255.255.255.0

 

tinc.confを作ったらrsaキーを作成します。

tincd -n vmnetz -K

 

メディアサーバと同じ設定にします。

cd vmnetz
cat libreelec
-----BEGIN RSA PUBLIC KEY-----

-----END RSA PUBLIC KEY-----
 Address = 192.168.1.5
 Port = 6555
 Subnet = 192.168.123.0/24

tinc.confのNameで指定したlinuxというファイルが出来ているので編集します。

Subnet = 192.168.123.2/32
 -----BEGIN RSA PUBLIC KEY-----

-----END RSA PUBLIC KEY-----

tincd -n vmnetz -Dでデバッグモードで起動してみます。Ctrl-Cで詳細モードになります。pingでサーバに到達していればVPNに繋がっています。
インターネットからアクセスする場合、LibreELECの設定でAddressが見えるようにする必要があります。今回はやりませんがDynamic DNSなどを使って設定します。またファイヤウォールでポートフォワーディングする必要もあります。この場合はポート6555です。

 

 

 

 

 

Armbian for S905Xを試す

AMlogicのS905Xは4コア1.6GhzのCPUなのでマルティメディア機能を捨ててもサーバとしても十分な性能があります。そこでサーバ用のイメージをSDにインストールしてみました。インストール方法はddで書き込んでもいいしWindowsならArmbianで紹介しているツールを使って書き込んでもOKです。

ROMイメージ

Linux Images for S802 S805 S812 S905 S905X S912 (SD USB eMMC)

内部メモリにインストールするには、nand-sata-installを実行すれば自動的にdataのパーティションにインストールします。カーネルモジュールが最小限しかないのでiptablesなど使ってルータ機能を持たせることはできませんが、ルータには入れられないFreeradiusやSquidなどのサーバはインストールでき十分性能を発揮できそうです。

Wi-Fiが認識出来ない場合はモジュールがないかロードしていないかのどちらかです。モジュール名がわかればロードします。

modprobe 8189es

/etc/modulesに追加すると次回のブートから自動的にカーネルモジュールがロードされてWi-Fiが使えるようになります。