Pop!_OS 20.04 LTSとwpa_supplicant

ひさしぶりにLinuxをたちあげたところなぜかWi-Fiがつながらないという事例がおきたので調べてみました。最初はカーネルが新しすぎてWi-Fiドライバーのすり合わせがうまくいってないのかと考えて旧カーネルでやってみても不具合が治らなかったのでwpa_supplicantを疑ってみました。この件についてはarmbianのTVBOXのときでも別の理由でダウングレードしたので、同じやり方で旧バージョンのBionicのwpa_supplicantにダウングレードしました。

journalctl --since="2020-11-14 00:00:00"

Nov 14 02:18:51 pop-os wpa_supplicant[987]: wlp3s0: Association request to the driver failed
Nov 14 02:18:51 pop-os kernel: ERROR @wl_set_key_mgmt : 
Nov 14 02:18:51 pop-os kernel: invalid cipher group (1027076)

radius serverはradiusd -Xでデバッグモードで起動しておきます。

cat <<'EOF' | sudo tee /etc/apt/sources.list.d/bionic.list
deb http://cz.archive.ubuntu.com/ubuntu bionic main
deb http://cz.archive.ubuntu.com/ubuntu bionic-updates main
EOF
apt-get update
apt-get install wpasupplicant=2:2.6-15ubuntu2.5
echo -e "Package: wpasupplicant\nPin: release o=Ubuntu,n=bionic\nPin-Priority: 1001" | \
 tee /etc/apt/preferences.d/bionic

前回とほぼおなじなのですが整理して再度掲載しました。これでwpa enterprise(TLS)ができるようになりました。

Posted in Linux | Comments Off on Pop!_OS 20.04 LTSとwpa_supplicant

(再) ELECOM WRC-1167GHBK2-SにOpenWrtをインストール

ELECOM WRC-1167GHBK2-SはOpenWrtのサポートがありますがWi-Fiが使えません。WLANがMediaTek MT7615Dというチップを使っていてそのサポートがないからです。しかしながら最新のSnapshot版では一応ドライバーは導入されておりWi-Fiが使えるようになっていますが、まだ不具合があります。MT7615D一つで2.4Gと5Gが使えるのですが、そのままですとどちらか一つのモードしか使えません。前回、5月にインストールを試してみたのですが、結果は良くありませんでした。今回はその時から改善を期待して再挑戦しました。

OpenWrtのフォーラムで調べてみると設定すれば使えるようです。/etc/config/wirelessを編集します。

config wifi-device 'radio0'
	option type 'mac80211'
	option path '1e140000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0'
	option htmode 'HT40'
	option disabled '0'

config wifi-iface 'default_radio0'
	option device 'radio0'
	option network 'lan'
	option disabled '0'
	option mode 'mesh'
	option mesh_id 'Mesh'
	option mesh_fwding '1'
	option mesh_rssi_threshold '0'
	option encryption 'sae'
	option key 'xxxxxxxxxxxxxxxx'
	#option wps_pushbutton '1'

config wifi-device 'radio1'
	option type 'mac80211'
	option hwmode '11a'
	option path '1e140000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0+1'
	option htmode 'VHT80'
	option disabled '0'
	option country 'JP'

config wifi-iface 'default_radio1'
	option device 'radio1'
	option network 'lan'
	option mode 'ap'
	option disabled '0'
	option ssid 'Network-5g'
	option encryption 'wpa2+ccmp'
	option auth_server '192.168.1.1'
	option auth_secret 'xxxxxxxx'
	option disassoc_low_ack '0'
        option disabled '0'

設定で大事なことはPhy0が2.4GでPhy1が5Gです。

次にコマンドを実行します。

wifi down
sleep 3
echo "1" > /sys/kernel/debug/ieee80211/phy0/mt76/dbdc
sleep 3
wifi up
echo e > /sys/class/net/eth0/queues/rx-0/rps_cpus

ip aを実行してWi-Fiデバイスが2つあることを確認します。さらにLuCIのダッシュボードで見てみます。

テストでは一応安定を保ってますが時たまphy1が不安定にあるときがあります。次期安定版では改善していることを期待したいところです。

Posted in OpenWrt | Comments Off on (再) ELECOM WRC-1167GHBK2-SにOpenWrtをインストール

Androidの静的ルーティング

今までOpenWrtやArmbianでネットワーク周りの設定をして、Androidのスマホの設定でどうしてできないものがありました。Andoridには静的ルーティングの設定項目の設定がありません。検索してみると2つほど解決策がありました。一つはsshでログインしてipコマンドで設定する方法です。2つ目はアプリをインストールすることです。

ipコマンドで静的ルーティングする場合

sshサーバをインストールします。いくつかアプリがあるのですが、SSHelperが良さそうだったのでインストールしました。sshコマンドでスマホにログインして、suコマンドでルートになります。ip route add <network> via <IP address>を実行すればできます。特に難しくはないのですが、毎回コマンドを打たなくてはいけないので面倒です。そこでアプリをインストールしてみました。

アプリから設定する場合

AIProuteをダウンロードします。

Androidアプリのソースコードらしいのですが、ビルドしたことがなかったので検索したところ、Android Studioをビルドできることがわかりました。macOSにインストールしたのですが、そう簡単にビルドできず、エラーが出るごとに不足している色々なパッケージをインストールして最終的にエラーが出なくなった時点でビルド完了となります。

https://mega.nz/folder/5fwxTaBI#zFNjDTuB4XVVddMXFCWSJQ

Posted in Android | Comments Off on Androidの静的ルーティング

Buffalo wmr-300のVLAN

ついこの間、ルーターに使っていたTVBOXのemmcが物理的に壊れて再構築することになりました。fsckで修復を試みたのですが、lxcのファイルがかなり壊れて修復不可能だったのでファイルシステムを再構築してクリーンインストールを試みました。ところがしばらくするとファイルシステムがread-onlyになってしましい、syslogにもファイルシステムのエラーが記録されてました。とりあえずはインターネットにつなぐルーターなので、余っているfon2405eで急場を凌ぎました。

同スペックの余っているTVBOXがあるので、それを使うことにしたのですが、元のルーターには複雑な設定になっており、そう簡単には復旧できません。LANポートが一つなのでVLANの設定、firewall、IPフォン用のsiproxd、WiFi用のfreeradiusとsnmpログのcactiと他にTinc、StrongSwan、WireguardのVPNとDDNSの設定と盛りだくさんです。急場凌ぎならfonでもいいのですが、メモリが32MBのため、freeradiusはちょっと無理そうです。そこでwmr-300なのですが64MBのメモリがあるので、バックアップ用のルータとして適任と思われるのですが、一つ問題がありました。OpenWrtの初期値でVLANが使えません。もともとLANポートが1つしかないので必要ないと言えばそれまでですが、MediatekのポピュラーのCPUなのでVLANが使えます。

そこで試行錯誤でVLANを使えるようにしました。fonの時もそうだったのですが、物理的のLANポートを探すことから始めます。物理ポートと違うポートにするとまず繋がりません。VLANを設定するには次の3つのファイルを編集します。

/etc/board.d/02_network: wmr-300-16Mを追加しました。wmr-300-16Mはwmr-300のSPIフラッシュを16MBに換装したものです。

ramips_setup_interfaces()
{
        local board="$1"

        case $board in
        ...
        
         wmr-300-16M)
                ucidef_add_switch "switch0" \
                        "4:lan" "6@eth0"
                ;;
        *)
                RT3X5X=`cat /proc/cpuinfo | egrep "(RT3.5|RT5350)"`
        ...

/etc/board.json: VLANのトポロジーを定義しているようです。追加します。

        ....
        "switch": {
                "switch0": {
                        "enable": true,
                        "reset": true,
                        "ports": [
                                {
                                        "num": 4,
                                        "role": "lan",
                                },
                                {
                                        "num": 6,
                                        "device": "eth0",
                                        "need_tag": false,
                                        "want_untag": false
                                }
                        ],
                        "roles": [
                                {
                                        "role": "lan",
                                        "ports": "4 6t",
                                        "device": "eth0.1"
                                },
                        ]
                }
        },
        ....

/etc/config/network: VLANの設定です

config switch
        option name 'switch0'
        option reset '1'
        option enable_vlan '1'

config switch_vlan
        option device 'switch0'
        option vlan '1'
        option vid '1'
        option ports '4 6t'

これでVLANが使えるようになりました。

Posted in OpenWrt | Comments Off on Buffalo wmr-300のVLAN

WireGuard with bridge interface?

色々調べてみてもWireGuardはLayer 3なのでTapデバイスは使えない。それゆえブリッジは無理っていう結論なのですが、調べてみるとなんとなくできそうなサイトが見つかりました。

GRE tunneling adds an additional GRE header between the inside and outside IP headers. In theory, GRE could encapsulate any Layer 3 protocol with a valid Ethernet type, unlike IPIP, which can only encapsulate IP.

An introduction to Linux virtual interfaces: Tunnels

2つのネットワークを同一ネットワークとして使うにはTunデバイスではなくTapデバイスを使います。WireGuardではTapデバイスが使えないのですが、サイトによると鍵はGRETAPを使うことです。そこが少し混乱するのですがIPv6で動くようです。これを使うにはカーネルモジュールのbr_netfilterをブート時にロードしておく必要があります。私のルーターで調べてみると、

br_netfilter           28672  0
bridge                233472  1 br_netfilter
ipv6                  622592  77 bridge,br_netfilter,wireguard

このようになっておりIPv6にbr_netfilterがリンクしています。そのあとはWireGuardのwg0.confでタップデバイスを立ち上げてブリッジインターフェースにリンクするという方法をとります。

PostUp = ip link add name gretap1 type gretap local 192.168.92.1 remote 192.168.178.1 
PostUp = ip link set gretap1 up
PostUp = ip link set gretap1 master br0

Tinc VPNではTapデバイスが使えるので簡単に同じネットワーク同士を繋ぐことができるのですが、WireGuardでも同様のことができるかもしれません。

OpenWrt

この情報をもとに早速OpenWrtで試してみました。機種はなんでも良いのですが先日、大量生産したOpenWrt化したfon2405eがあるのでそれを使いました。なかなか思うようにいかずOpenWrtのフォーラム等で検索して何度かトライしたらできました。

まずは802.11sの暗号なしのメッシュネットワークを作ります。次にWireGuardのネットワークを作ります。この時問題なのがWireGuardの設定をするとパケットが全てDefualt Gatewayに流れてしまい接続ができなくなるので、手動でルーティングから削除します。OpenWrtのリポジトリからGretapのパッケージをインストールして/etc/config/networkの設定をします。

packages

gre - 1-11
kmod-gre - 4.14.195-1
kmod-gre6 - 4.14.195-1
kmod-br-netfilter - 4.14.195-1

WireGuard (interface)

Firewall

General SettingsのInputを有効にしないとなぜか繋がりません。

/etc/config/network

'''

config interface 'lan'
	option type 'bridge'
	option proto 'static'
	option ipaddr '192.168.1.17'
	option netmask '255.255.255.192'
	option ip6assign '60'
	option gateway '192.168.1.1'
	list dns '8.8.8.8'
	list dns '1.1.1.1'
	option macaddr 'xx:xx:xx:xx:xx:xx'
	option ifname 'eth0.1 gre4t-gt'


...

config interface 'mesh'
	option proto 'static'
	option netmask '255.255.255.0'
	option ipaddr '10.101.0.17'

config interface 'wg'
	option proto 'wireguard'
	option private_key 'xxxxxxxxxxxxxxxx'
	option listen_port '8889'
	list addresses '192.168.2.17/26'

config wireguard_wg
	option public_key 'xxxxxxxxxxxxxxxx'
	option persistent_keepalive '25'
	option endpoint_port '8888'
	option endpoint_host '10.101.0.14'
	list allowed_ips '192.168.2.0/26'
	list allowed_ips '10.101.0.0/24'
	list allowed_ips '192.168.1.0/26'

config interface 'gt'
    option type 'bridge'
	option proto 'gretap'
	option ipaddr '192.168.2.17'
	option peeraddr '192.168.2.14'
	#option force_link '1'
	#option mtu '1500'
    option delegate '0'

ルーティングの修正

ip r del 10.101.0.14 via 192.168.1.1
ip r del 192.168.2.14 via 192.168.1.1

追記

firewallの追加です。

/etc/firewall.user

iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu;

routingの問題はOpenWrt仕様の特有の問題なので、それを回避するためにInterfacesの設定ではDefault GWの設定はしません。その代わりにあまり良い方法とは言えませんがrc.localで設定します。

/etc/rc.local

sleep 20
ip route add default via 192.168.1.1 dev br-lan

exit 0

追記1.1

OpenWrtのソースを眺めていたら、隠し設定があるらしいことに気がつきました。検索して調べてみると公式HPでも記述がありました。Wireguardをデフォルトルート以外で使うときはこの設定(option nohostroute '1')を使えば良さそうです。

  • https://openwrt.org/docs/guide-user/network/tunneling_interface_protocols

/etc/config/network (例)

onfig interface 'wg'
	option proto 'wireguard'
	option private_key 'xxxxxxxxxxxxxxxx'
	option listen_port '8001'
	option nohostroute '1'
	list addresses '192.168.2.6/26'

config wireguard_wg
	option endpoint_port '8000'
	option public_key 'xxxxxxxxxxxxxxxx'
	option endpoint_host '10.200.0.100'
	option persistent_keepalive '25'
	option nohostroute '1'
	list allowed_ips '192.168.1.0/26'
	list allowed_ips '192.168.2.0/26'

config interface 'gt'
	option type 'bridge'
	option proto 'gretap'
	option ipaddr '192.168.2.6'
	option peeraddr '192.168.2.5'
	option nohostroute '1'
	option delegate '0'

追記2

Firewallルールを少し変えてみました。

General settingsのInputをrejectにした場合、greプロトコルを通すためにiptablesのルールを追加します。

/etc/firewall.user

iptables -I INPUT -p gre -j ACCEPT
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu;

さらにOpenWrtのパッケージをインストールします。

opkg install kmod-ipt-nat-extra

参考

  • https://notes.superlogical.ch/pages/note_wg/nolayer2/
  • https://openwrt.org/docs/guide-user/network/tunneling_interface_protocols
  • https://forum.openwrt.org/t/setup-fastest-pseudowire-protocol/36219/11
  • https://forum.openwrt.org/t/solved-gretap-tunnel-with-vlan-802-1q-tagging/20742/2
  • https://backreference.org/2013/07/23/gre-bridging-ipsec-and-nfqueue/
  • https://developers.redhat.com/blog/2019/05/17/an-introduction-to-linux-virtual-interfaces-tunnels/
  • https://medium.com/@david.waiting/a-beginners-guide-to-generic-routing-encapsulation-fb2b4fb63abb
  • https://forum.archive.openwrt.org/viewtopic.php?id=59150

Posted in Linux | Comments Off on WireGuard with bridge interface?

UPDATE: Kindle Weather Display

OpenWeatherMapのHPを見ていたらOne Call APIというのが新設されていて、現在、時間ごと、日付ごとの天気情報のデータを一度にダウンロードできるAPIがありました。今までは3時間ごとの天気情報をマニアックなやり方で日ごとの予測を弾き出していたのですが、このAPIを使えばシンプルなプログラムになります。この際なのでAPIをモジュール化して整理しました。ところが問題があって、すべてのローケーションでOne Call APIが使えるわけではなく、一部データが欠損するということがわかりました。まだ安定して使えないということです。それなので旧バージョンと新バージョンを分けることにしました。One Call APIは降雨予想があったので雲アイコンに載せてみました。

Posted in kindle | Comments Off on UPDATE: Kindle Weather Display

OpenWrt: mac addressの書き換え

数台のfon2405eのSPiフラッシュを載せ替えたまではいいのですが、一つ困った大きな問題があります。同じROMなのでmac addressが同じになってしまい、同時に起動していると通信障害が置きます。arpコマンドでHW addressを見てみればわかるように、同じmac addressだと衝突します。OpenWrtには/config/networkでmac addressのカスタム設定という方法があるのですが、なぜかfonには使えません。そこでフラッシュROMのEEPROM書き換えてmac addressを変えてみます。OpenWrtで予備知識を得られるのでまず目を通して置きます。

  • https://openwrt.org/docs/guide-user/installation/restore_art_partition
  • https://openwrt.org/docs/guide-developer/mac.address

これによると、rt305xの場合は+4なのでhexdumpで確認します。

hexdump -n 100 -C mtd2.bin
00000000  50 30 00 01 00 0c 43 30  50 88 ff ff ff ff ff ff  |P0....C0P.......|
00000010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000020  ff ff ff ff ff ff ff ff  00 0c 43 30 50 77 00 0c  |..........C0Pw..|
00000030  43 30 50 66 11 05 24 00  ff ff 2f 01 55 77 a8 aa  |C0Pf..$.../.Uw..|
00000040  8c 88 ff ff 0c 00 00 00  00 00 00 00 00 00 ff ff  |................|
00000050  ff ff 0d 0d 0d 0d 0c 0c  0c 0c 0c 0c 0c 0c 0c 0c  |................|
00000060  10 10 11 11                                       |....|
00000064

00 0c 43 30 50 88がralink SDKで作ったEEPROMのmac addressと一致しました。

そこで先頭のmac addressだけ変更することにします。

echo -n -e '\x01' | dd of=mtd2.bin bs=1 seek=4 conv=notrunc

hexdump -n 100 -C mtd2.bin
00000000  50 30 00 01 01 0c 43 30  50 88 ff ff ff ff ff ff  |P0....C0P.......|
00000010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000020  ff ff ff ff ff ff ff ff  00 0c 43 30 50 77 00 0c  |..........C0Pw..|
00000030  43 30 50 66 11 05 24 00  ff ff 2f 01 55 77 a8 aa  |C0Pf..$.../.Uw..|
00000040  8c 88 ff ff 0c 00 00 00  00 00 00 00 00 00 ff ff  |................|
00000050  ff ff 0d 0d 0d 0d 0c 0c  0c 0c 0c 0c 0c 0c 0c 0c  |................|
00000060  10 10 11 11                                       |....|
00000064

先頭が変わって01 0c 43 30 50 88になりました。これをmtdに書き込んで再起動します。

opkg install kmod-mtd-rw --force-depends
insmod /lib/modules/4.14.195/mtd-rw.ko i_want_a_brick=1
mtd -r write mtd2.bin factory

確かに変わってるのですが、期待したものと全く違っていました。原因は不明なもののmac addressの変更はこれでできました。

4: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether 12:16:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
Posted in OpenWrt | Comments Off on OpenWrt: mac addressの書き換え

Kindle: timelitのdark mode

Kindle weather displayとKindle news feed displayをダークモード対応にしたのでtimelitも対応させることにしました。自動的に切り替えは意外と落とし穴があって難しい。Kindle weatherは取り寄せるデータに日の出、日の入りがあるのでそのまま使えます。タイムゾーンに合わせてあるので問題は起こりません。ところがPythonモジュールで計算するとUTCを基準にしているので日付がずれます。これはなかなか厄介ですが、日付部分を取り除いて比較すればできます。当然、1日分違うため数分のずれが生じるので正確ではありませんがアプリケーションの精度からみて問題ありません。

timelitはもう少し複雑です。シェルでPythonを動かすのであまり複雑なスクリプトは組めません。さらにPython2なのでPython3より複雑になります。さらにpip等でモジュールをインストールできないので自前で用意しなければなりません。

色々調べると解決策がいくつかあり、特にモジュールをインストールしなくても比較的簡単に算出できる方法がありました。このスクリプトの問題は、日付を無視するので時間だけの情報になります。

Sun.py

import math
import datetime
import time

class Sun:

    def getSunriseTime( self, coords ):
        return self.calcSunTime( coords, True )

    def getSunsetTime( self, coords ):
        return self.calcSunTime( coords, False )

    def getCurrentUTC( self ):
        now = datetime.datetime.now()
        return [ now.day, now.month, now.year ]

    def calcSunTime( self, coords, isRiseTime, zenith = 90.8 ):

        # isRiseTime == False, returns sunsetTime

        day, month, year = self.getCurrentUTC()

        longitude = coords['longitude']
        latitude = coords['latitude']

        TO_RAD = math.pi/180

        #1. first calculate the day of the year
        N1 = math.floor(275 * month / 9)
        N2 = math.floor((month + 9) / 12)
        N3 = (1 + math.floor((year - 4 * math.floor(year / 4) + 2) / 3))
        N = N1 - (N2 * N3) + day - 30

        #2. convert the longitude to hour value and calculate an approximate time
        lngHour = longitude / 15

        if isRiseTime:
            t = N + ((6 - lngHour) / 24)
        else: #sunset
            t = N + ((18 - lngHour) / 24)

        #3. calculate the Sun's mean anomaly
        M = (0.9856 * t) - 3.289

        #4. calculate the Sun's true longitude
        L = M + (1.916 * math.sin(TO_RAD*M)) + (0.020 * math.sin(TO_RAD * 2 * M)) + 282.634
        L = self.forceRange( L, 360 ) #NOTE: L adjusted into the range [0,360)

        #5a. calculate the Sun's right ascension

        RA = (1/TO_RAD) * math.atan(0.91764 * math.tan(TO_RAD*L))
        RA = self.forceRange( RA, 360 ) #NOTE: RA adjusted into the range [0,360)

        #5b. right ascension value needs to be in the same quadrant as L
        Lquadrant  = (math.floor( L/90)) * 90
        RAquadrant = (math.floor(RA/90)) * 90
        RA = RA + (Lquadrant - RAquadrant)

        #5c. right ascension value needs to be converted into hours
        RA = RA / 15

        #6. calculate the Sun's declination
        sinDec = 0.39782 * math.sin(TO_RAD*L)
        cosDec = math.cos(math.asin(sinDec))

        #7a. calculate the Sun's local hour angle
        cosH = (math.cos(TO_RAD*zenith) - (sinDec * math.sin(TO_RAD*latitude))) / (cosDec * math.cos(TO_RAD*latitude))

        if cosH > 1:
            return {'status': False, 'msg': 'the sun never rises on this location (on the specified date)'}

        if cosH < -1:
            return {'status': False, 'msg': 'the sun never sets on this location (on the specified date)'}

        #7b. finish calculating H and convert into hours

        if isRiseTime:
            H = 360 - (1/TO_RAD) * math.acos(cosH)
        else: #setting
            H = (1/TO_RAD) * math.acos(cosH)

        H = H / 15

        #8. calculate local mean time of rising/setting
        T = H + RA - (0.06571 * t) - 6.622

        #9. adjust back to UTC
        UT = T - lngHour
        UT = self.forceRange( UT, 24) # UTC time in decimal format (e.g. 23.23)

        #10. Return
        hr = self.forceRange(int(UT), 24)
        min = round((UT - int(UT))*60,0)

        def convert_unix_time(datetime_obj):
            return int(time.mktime(datetime_obj.timetuple()))

        unixtime = convert_unix_time(datetime.datetime(int(year), int(month), int(day), int(hr), int(min), int(0)))

        return {
            'status': True,
            'decimal': UT,
            'hr': hr,
            'min': min,
            'unixtime': unixtime
        }

    def forceRange( self, v, max ):
        # force v to be >= 0 and < max
        if v < 0:
            return v + max
        elif v >= max:
            return v - max

        return v

timelit.sh.diff

--- timelit.sh.orig	2020-09-17 22:45:55.414873702 +0000
+++ timelit.sh	2020-09-17 22:45:37.886601266 +0000
@@ -1,11 +1,19 @@
 #!/bin/bash

+cd "$(dirname "$0")"
+
 # if the Kindle is not being used as clock, then just quit
 test -f /mnt/us/timelit/clockisticking || exit

+# my latitude and longitude
+lat=35.8034315
+lng=139.4275599
+offset=+9
+dark_mode='Auto'

 # find the current minute of the day
-MinuteOTheDay="$(env TZ=CEST date -R +"%H%M")";
+#MinuteOTheDay="$(env TZ=CEST date -R +"%H%M")";
+MinuteOTheDay="$(env TZ=GMT-9 date -R +"%H%M")";

 # check if there is at least one image for this minute
 lines="$(find /mnt/us/timelit/images/quote_$MinuteOTheDay* 2>/dev/null | wc -l)"
@@ -16,9 +24,40 @@
 	echo $lines' files found for '$MinuteOTheDay
 fi

+exec_dark_mode() {
+    t_sunrise=$(python -c "from Sun import Sun; coords = {'longitude' : $lng, 'latitude' : $lat }; sun = Sun(); print sun.getSunriseTime( coords )['unixtime']")
+    t_sunset=$(python -c "from Sun import Sun; coords = {'longitude' : $lng, 'latitude' : $lat }; sun = Sun(); print sun.getSunsetTime( coords )['unixtime']")
+    t_now=$(date '+%s')
+
+    [ "$t_sunrise" -gt "$t_sunset" ] && t_sunrise=$(( $t_sunrise - 86400 ))
+
+    t_sunrise=$(( ($t_sunrise + $offset * 3600) % 86400 ))
+    t_sunset=$(( ($t_sunset + $offset * 3600) % 86400 ))
+    t_now=$(( ($t_now + $offset * 3600) % 86400 ))
+
+    if [ "$t_now" -lt "$t_sunrise" ] || [ "$t_now" -gt "$t_sunset" ]; then
+        mode='dark_mode/'
+    else
+        mode=''
+    fi
+}
+
+case "$dark_mode" in
+    "Auto")
+        exec_dark_mode
+        ;;
+    "True")
+        mode='dark_mode/'
+        ;;
+    *)
+        mode=''
+        ;;
+esac
+

 # randomly pick a png file for that minute (since we have multiple for some minutes)
-ThisMinuteImage=$( find /mnt/us/timelit/images/quote_$MinuteOTheDay* 2>/dev/null | python -c "import sys; import random; print(''.join(random.sample(sys.stdin.readlines(), int(sys.argv[1]))).rstrip())" 1)
+#ThisMinuteImage=$( find /mnt/us/timelit/images/quote_$MinuteOTheDay* 2>/dev/null | python -c "import sys; import random; print(''.join(random.sample(sys.stdin.readlines(), int(sys.argv[1]))).rstrip())" 1)
+ThisMinuteImage=$( find /mnt/us/timelit/images/${mode}quote_$MinuteOTheDay* 2>/dev/null | python -c "import sys; import random; print ''.join(random.sample(sys.stdin.readlines(), int(sys.argv[1]))).rstrip()" 1)

 echo $ThisMinuteImage > /mnt/us/timelit/clockisticking

dark mode用の画像を作成します。

mkdir /mnt/us/timelit/images/dark_mode
cd /mnt/us/timelit/images/dark_mode

convert.sh

#!/bin/sh

ls ../*.png |while read f; do
    echo -n "- converting ${f#../}:"
    convert -size 600x800 -background white -depth 8 -negate "$f" "${f#../}"
    pngcrush -s -c 0 -ow "${f#../}"
    echo " result $?"
done

ソース

  • https://www.instructables.com/id/Literary-Clock-Made-From-E-reader/
  • https://stackoverflow.com/questions/19615350/calculate-sunrise-and-sunset-times-for-a-given-gps-coordinate-within-postgresql
Posted in Linux | Comments Off on Kindle: timelitのdark mode

dropbear client: pub-key authentication

今まではOpenssh Clientを使ったpub-keyのsshアクセスをやっていましたが、どうも漠然とした疑問があり、デフォルトインストールの dropbearでpub-keyアクセスはできないものかとずっと思っていました。というのはOpenWrtをインストールしたルーターは厳しい容量で運用しなければなりません。せっかくdropbeaarがあるのにOpensshクライアントを入れるのは無駄だと思われるからです。

色々と調べてみてどうやらできることがわかりました。

手順

OpenWrtは導入後に秘密鍵を持っています。それをpub-keyに変換します。

cd /etc/dropbear
dropbearkey -y -f dropbear_rsa_host_key | grep "^ssh-rsa " > dropbear_rsa_host_key.pub

秘密鍵をデフォルトローケーションに置きます。

mkdir /root/.ssh
cd /root/.ssh
ln -s /etc/dropbear/dropbear_rsa_host_key id_dropbear

pug-keyをリモート先のdropbearに登録します。

scp dropbear_rsa_host_key.pub root@<remote IP>:/tmp
ssh root@<remote IP>

[remote login]

cd /etc/dropbear
cat /tmp/dropbear_rsa_host_key.pub >> authorized_keys

秘密鍵を指定してログインする方法

ssh root@<remote IP> ~i /etc/dropbear/dropbear_rsa_host_key
Posted in OpenWrt | Comments Off on dropbear client: pub-key authentication

buffalo wmr-300(トラベルルータ)のフラッシュROMを16MBに換装

fon2405eでSPIフラッシュROMを取り替えが成功したので、他のルーターもやってみました。取り寄せたSPIフラッシュメモリの在庫がかなりあるのでできれば16MBにすれば使い勝手がかなり向上します。8MBでも十分OpenWrtが使えるのですが、本格的に使おうとすると最低16MBは必要です。wmr-300はかなり小さいくトラベルルータとして持ち運びでき重宝するので、SPIフラッシュを取り替えることにしました。

今回はfon2405eの時のようにu-bootからファームウェアを焼かずに、フラッシュROM全体を移し替えます。下図のログは換装後の16MBフラッシュROMですが、”u-boot”、”u-boot-env”、 “factory” 、”firmware”をddコマンドで吸い出して、catコマンド繋ぎ合わせれば、アドレスの連続したファイルが出来上がり全体のフラッシュROMのコピーになります。”firmware”パーティションのアドレスが物理アドレスより大きくなっていますが、物理的に切られるので問題ありません。そのコピーを直接、フラッシュROMに書き込みます。書き込み後、ブートしてデバイスツリーでパーティションを拡大してビルドした新しいファームウェアにアップグレードします。

[    0.540941] m25p80 spi0.0: mx25l12805d (16384 Kbytes)
[    0.551116] 4 fixed-partitions partitions found on MTD device spi0.0
[    0.563789] Creating 4 MTD partitions on "spi0.0":
[    0.573341] 0x000000000000-0x000000030000 : "u-boot"
[    0.584223] 0x000000030000-0x000000040000 : "u-boot-env"
[    0.595739] 0x000000040000-0x000000050000 : "factory"
[    0.606752] 0x000000050000-0x000001000000 : "firmware"
[    0.620737] 2 uimage-fw partitions found on MTD device firmware
[    0.632600] Creating 2 MTD partitions on "firmware":
[    0.642510] 0x000000000000-0x00000017e04d : "kernel"
[    0.653323] 0x00000017e04d-0x000000fb0000 : "rootfs"
[    0.664142] mtd: device 5 (rootfs) set to be root filesystem
[    0.676980] 1 squashfs-split partitions found on MTD device rootfs
[    0.689368] 0x000000380000-0x000000fb0000 : "rootfs_data"

mt7620だと16MB以上のフラッシュROMを積めるのですが、問題はu-bootが対応していないとブートできないという問題があります。u-bootのソースはあるにはあるのですが、いざコンパイルして使うとなるとリスクが大きすぎます。今回は余っているフラッシュROMを使うことにしたので、16MBまでならオリジナルのu-bootで十分対応可能です。

OpenWrtはデバイスツリーをSPIフラッシュROMを16MB用に変えるだけで他には変更は加えていません。

リソース

UPDATE

バグはできるだけ潰したのですがどうしても一つだけ潰せないものがありました。デフォルトのネットワークの設定がどうしてもswitchの仕様になります。解決方法はfailesafeでsshログインしてmount_rootでrootfsにマウントし/overlay/upper/etc/config/networkを書き換えます。

config interface 'loopback'
	option ifname 'lo'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'

config globals 'globals'
	option ula_prefix 'fd7a:751a:4b5e::/48'

config interface 'lan'
	option type 'bridge'
	option ifname 'eth0'
	option proto 'static'
	option ipaddr '192.168.211.1'
    option netmask '255.255.255.0'
	option ip6assign '60'

config device 'lan_eth0_dev'
	option name 'eth0'
	option macaddr 'xx:xx:xx:xx:xx:xx'

Posted in OpenWrt | Comments Off on buffalo wmr-300(トラベルルータ)のフラッシュROMを16MBに換装