Quantcast
Channel: Linux Install Memo
Viewing all 69 articles
Browse latest View live

□RTX1200でLTEドングルを使ってみる(テスト版)

$
0
0

先日の温泉合宿で使った「LTEモバイルルーター(BF-01D)+PlanexのVPN対応ルーター(VPN-41FE)」という構成で回線状態がメタメタだったので、ここはやっぱりYAMAHAさんか?RTXか?ということで知り合いのショップからRTX1200の中古をポチってテストしてみました。

ちなみにVPN-41FEはVPN対応だったのでそれなりの処理能力はあるだろう、 とおもっていたのだけど、実際には参加した生徒さんのsshとかwebとか切れまくりでひどいありさまだった(ごめんなさいごめんなさいごめんなさい) のでPlanexに性能を聞いてみたのだけど、どうやら問題はそこではないらしい。

そもそも事前の負荷テスト(abとかcurl-loader)では問題が露呈しなかったので、これはルーターのせいではないのかもしれない、という思いもあった。

その辺の検証もかねて、今回は月末のサーバー構築ハンズオンでの実地試験の準備を兼ねて、RTX1200をLAN接続(LANがないときにはLTE接続)、という構成で設定してテストしてみた。

CATVインターネットなどイーサネット回線を利用する
http://jp.yamaha.com/products/network/solution/internet/catv/

WAN回線障害時に備える(モバイルバックアップ)
http://jp.yamaha.com/products/network/solution/internet/internet-mobile_backup-rtx1200/

モバイルインターネット接続機能
http://www.rtpro.yamaha.co.jp/RT/docs/mobile-internet/index.html

この辺を参照しつつ、手元にある

DoCoMo L-02C 75Mbps/25Mbps

IIJmioの標準SIM(10GBファミリーシェア)をさしてみた。

基本はLAN3にインターネット回線を有線接続するが、そのような設備がない 場所では、LTEのUSBドングルでインターネットに接続する。

ポイントとしては

  • NAT descriptor IDはLAN3が1、LTE(pp 2)が2としてそれぞれを設定。
  • LAN3はGoogleさんのDNS(8.8.8.8)にkeepaliveでicmp-echoして回線状況監視。
  • で、LAN3のバックアップ回線としてLTE(pp 2)を指定。
  • DNSはGoogleさんのDNS(8.8.8.8, 8.8.4.4)を設定。
  • 回線切り替え判定は10秒くらいでするように設定。(待つのが面倒)

NATは回線別にdescriptor IDをわけないと、バックアップで切り替わった時に 外に出ていけなかった。

またDNSはdns server selectで回線毎に設定したかったがうまくいかなかった。

で、L-02Cをさすとこんな感じでちゃんと認識してくれる。

2016/03/09 15:07:11: [USB_HOST] device attached : vendor=0x1004 <NTT DOCOMO, INC.>, product=0x618f <docomo L02C>
2016/03/09 15:07:11: [USB_HOST] USB communication device is attached

ただし、RTX1200の起動直後はmobile signal-strength goで電波の強さを見ても

[MOBILE] Signal Strength (0-5): – [圏外] (usb1)

というように圏外扱い。

さらに、実際にLTE接続しているときには

[MOBILE] Signal Strength (—): PPインタフェース接続中です (usb1)

となって利用中は調べられない。

一度LTEが切断されないと判らないのは、仕組み上しょうがないんだろうけど、 RTX1200起動時に調べられないのはちょっと不便かも。なので起動時に強制的に 一度接続してしまうようにLuaでもなんでもいいから設定するといいかも?
(まぁLANケーブルを抜いたままで起動して、あとからさしてもいいんだけど)

で、実際にLANケーブルをぶちっと抜けば

2016/03/09 15:07:57: LAN3: link down
2016/03/09 15:08:01: [LAN] LAN3: switched to backup
2016/03/09 15:08:02: PP[02] IP Commencing: ICMP 192.168.120.100 > 8.8.8.8 : echo request
2016/03/09 15:08:02: PP[02] Calling iijmio.jp with usb1
2016/03/09 15:08:02: USB[1] SEND [ATD*99***2#]
2016/03/09 15:08:02: USB[1] RECV [CONNECT]
2016/03/09 15:08:02: USB[1] Connected
2016/03/09 15:08:05: [LAN] LAN3 Detect down via ping keepalive
2016/03/09 15:08:27: PP[02] PPP/IPCP up  (Local: 100.76.104.203, Remote: None)

LTEに切り替わる。

で、LAN3にLANケーブルをさし戻して、監視先にicmp-echoが通れば、

2016/03/09 15:10:39: LAN3: link up (1000BASE-T Full Duplex)
2016/03/09 15:10:39: [LAN] LAN3: recovered from backup
2016/03/09 15:10:39: PP[02] Disconnecting, cause [No error.]
2016/03/09 15:10:39: USB[1] SEND SIGNAL [DTR=OFF]
2016/03/09 15:10:39: USB[1] RECV [NO CARRIER]
2016/03/09 15:10:43: PP[02] Disconnected, cause [No error.]

というように、LTEは自動的に切断して経路も切り替わるし、電波の強さも

[MOBILE] Signal Strength (0-5): 5 [|||] (usb1)

こんな感じで確認することができる。

 

■いくつか検証

1.ppとwan1だとwan1の方が速い!?

モバイルインターネット接続機能
http://www.rtpro.yamaha.co.jp/RT/docs/mobile-internet/index.html#cellphones

ここに

「PPインターフェース接続及びWANインターフェース接続共に対応している携帯端末の中には、
WANインターフェース接続の方が通信速度が速いものがあるため、WANインターフェース接続
にて利用することを推奨します。」

とあるので試してみた。(ただし、wan1をlan3のbackupにはできない)

L-02C(pp接続時)

  • Ookla DOWN:8.07Mbps, UP:5.99Mbps (sumida) pingタイムアウト数回
  • Ookla DOWN:6.97Mbps, UP:5.91Mbps (sumida) pingタイムアウト数回
  • Ookla DOWN:8.10Mbps, UP:4.73Mbps (tokyo) pingタイムアウト数回
  • USEM 3.824Mbps pingタイムアウトなし
  • USEM 6.038Mbps pingタイムアウトなし
  • USEM 3.993Mbps pingタイムアウトなし

L-02C(wan接続時)

  • Ookla 途中で切断
  • Ookla 途中で切断
  • Ookla DOWN:11.99Mbps, UP:12.45Mbps (sumida) pingタイムアウト数回
  • USEM 4.045Mbps
  • USEM 途中で切断
  • USEM 10.637Mbps

wan接続の方が安定しないので、pp接続の方がいいのかな?

どちらにしても、wan接続はバックアップとして設定できないのでpp接続にするしかないんだけど。

ちなみに、切れるときには以下のようにログ出力がある

2016/03/10 11:13:30: PP[02] Disconnected, cause [WAN connector trouble]
2016/03/10 11:13:30: [USB_HOST] device detached : vendor=0x1004 <NTT DOCOMO, INC.>, product=0x618f <docomo L02C>
2016/03/10 11:13:30: [MOBILE] Signal Strength (—): Could not find communication device. (usb1)
2016/03/10 11:13:31: [USB_HOST] Bus reset done
2016/03/10 11:13:35: PP[02] Mobile device is not attached. Call request is rejected
2016/03/10 11:13:35: [USB_HOST] device attached : vendor=0x1004 <NTT DOCOMO, INC.>, product=0x618f <docomo L02C>
2016/03/10 11:13:35: PP[02] Mobile device is not attached. Call request is rejected
2016/03/10 11:13:35: [USB_HOST] USB communication device is attached

L-02Cが悪いのか?それともLTE網が悪いのか、(´ε`;)ウーン…。

2.帯域制御

QoS機能の動作
http://jp.yamaha.com/products/network/solution/advanced/qos/point/

にある方法で試したが、LAN3やpp 2から出ていく帯域を絞るといいのかな?
と思ったのだけど、どうしてもシェービングできない。

理由はこちら。

「制御できるのは出力トラフィックだけ」

帯域制御のふるまい
http://www.rtpro.yamaha.co.jp/RT/FAQ/Queue/queue-type-cbq.html

のこと。

なので、LAN1、LAN3、pp 2それぞれから出ていくパケットを絞ることで、上り下りともに帯域制御ができた。

3.OSとかアップデート制限

MicrosoftとかAppleとかのアップデートの際にアクセスするURLについて、url filterで、LAN3とpp 2からout方向にフィルターをした。

まんまとアクセスできません。:-)

4.LAN3にBF-01Dを接続するとどうなるか?

温泉合宿の時はL-02Cではなくて、BF-01Dの下に某ルータをぶら下げたので、同様にBF-01Dの下にRTX1200をぶら下げた状態でトラフィック負荷がかかった時にどうなるか確認してみる。

何回か負荷をかけると、やはり温泉合宿の時と同様のメタメタになった。(´Д`)ハァ…

pingは通っているのに(パケットロスしたりもするけど)WEBが通らないという状態はまさに温泉合宿の時と同じ。

これはBF-01Dの問題ってことかな?

 

■いろいろ検証してみて…

制限なくトラフィックをかけるとL-02Cは落ちるので、これは帯域制御で回避できるようになった。

LAN3も同様の帯域制御(上り/下りどちらも10Mbps)が効いてるのに、BF-01Dを接続した場合はWEBとかにアクセスできないというような問題が発生した。

このことから

  • BF-01Dはルーターモードでトラフィック負荷がかかると動作がおかしくなる。
    (配下のルーターがなんであるかは関係ないっぽい)
  • RTX1200+L-02Cでもトラフィック負荷がかかったりすると、接続が切れる。
    (PP[02] Disconnected, cause [WAN connector trouble]で)

というわけで構成としては後者の方がまだまし。(再接続してくれるしね)

もっとも、後者の切れるときの切断コード(WAN connector trouble)は、YAMAHAによると

「WANポートの回線コネクタ抜けにより発信失敗」

切断コード表
http://www.rtpro.yamaha.co.jp/RT/docs/misc/disconnect-code.html

らしいので、もしかしたら別のLTEドングルにしたら、もっと安定するかも?と淡い期待を抱いてしまうなぁ…

 

■今後の予定

というわけで、今後の予定は

  • RTX1200+L-02Cでハンズオンで実際に使ってみる。
    (使い心地の検証)
  • L-02C以外の、新しめのLTEドングルで試してみる。
    (セッションが切れるかどうか)

ですかね。


□RTX1200でL-03Fを使ってみる(テスト版)

$
0
0

週末に最新(?)のクアッドバンド対応のL-03Fを入手したので、同様にテストをしてみました。

DoCoMo L-03F 150Mbps/50Mbps, 800MHz対応

お、L-03Fは刺したら勝手に電波の強さがわかるみたいですね。

2016/03/14 12:43:46: [USB_HOST] device attached : vendor=0x1004 <NTT DOCOMO, INC.>, product=0x6366 <docomo L03F>
2016/03/14 12:43:46: [USB_HOST] USB communication device is attached
2016/03/14 12:43:52: [MOBILE] Signal Strength (0-31): 14 [|| ] (usb1)
2016/03/14 12:44:23: same message repeated 2 times
2016/03/14 12:44:23: [MOBILE] Signal Strength (0-31): 13 [|| ] (usb1)
2016/03/14 12:44:43: same message repeated 1 times
2016/03/14 12:44:43: [MOBILE] Signal Strength (0-31): 14 [|| ] (usb1)
2016/03/14 12:44:57: same message repeated 1 times

では早速L-03Fを使って先日と同様のテストをしてみます。

L-03F(pp接続時)

平日12:45前後

  • Ookla DOWN:0.67Mbps, UP:2.40Mbps (tokyo) pingタイムアウト数回
  • Ookla DOWN:1.21Mbps, UP:2.05Mbps (Fussa-shi) pingタイムアウト数回
  • Ookla DOWN:1.30Mbps, UP:2.69Mbps (Fussa-shi) pingタイムアウト数回
  • USEM 0.422Mbps pingタイムアウトなし
  • USEM 0.462Mbps pingタイムアウトなし
  • USEM 0.474Mbps pingタイムアウトなし

平日13:05前後

  • Ookla DOWN:8.27Mbps, UP:4.53Mbps (sumida) pingタイムアウト数回
  • Ookla DOWN:9.18Mbps, UP:4.90Mbps (Tokyo) pingタイムアウト数回
  • Ookla DOWN:9.18Mbps, UP:6.14Mbps (Fussa-shi) pingタイムアウト数回
  • USEM 6.349Mbps pingタイムアウトなし
  • USEM 6.028Mbps pingタイムアウトなし
  • USEM 6.313Mbps pingタイムアウトなし

まぁL-02Cで試した時とあんまり変わらないかな?

それにしても、ホント、お昼休みの12時台だけは遅いなぁ…

□メールサーバー間通信でもTLS

$
0
0

シマンテックさんから「GoogleがGmailで非暗号化メールに「鍵」警告アイコンを表示」なんてメールが来ていたので、ふむふむ、TLS対応しているメールサーバーなら大丈夫だな…(゚ε゚)ブホッ、できてねーじゃねーか!!

というわけで調べてみたところ、TLS対応してるPostfixのmain.cfに

smtpd_use_tls = yes

じゃなくて

smtp_use_tls = yes

と書かないといけないらしい。

前者はクライアントサーバーとのやり取り、後者はサーバー間のやり取り、についてTLSがOKなら使うかどうか、ということ。

また「セキュアなプロトコルを使ってみよう」を加筆修正しなきゃ。

( ´Д`)=3 フゥ

□fail2banをやめてBan4ipにしませんか?

$
0
0

fail2banは気軽にうざいアクセスをシャットアウトしてくれる便利なツールですが、残念ながらIPv6には対応していません

自分のサーバーはIPv6に非対応だから大丈夫、という方はそのままfail2banでもOKですが、IPv6にも対応して時代の最先端に踊り出るぜ、という方はfail2banは使えませんので、同様のツールがないとすぐにサーバーをクラックされかねません。

いや、クラックされないようにしているよ、という方も、うざいアクセスはシャットアウトしたいですよね。

そんな方のために、IPv4とIPv6の両方に対応した「Ban4ip」を作りました。

「Ban4ip」はfail情報が含まれたログファイルを読み込みながら、iptablesでIPアドレスをBANするツールです。
ログファイルに出力されている相手のIPアドレスをそのままBANの対象としますので、IPv4とIPv6とかの区別がありません。
そして、「Ban4ip」はfail2banのようにうざいIPアドレスをBANします。

みんな待ってたでしょ?

全てのサーバー管理者と、あなたのサーバーにアクセスするIPv4&IPv6ユーザーのために、「Ban4ip」をお勧めします。

https://github.com/disco-v8/Ban4ip.git

#だれかGitHUBの使い方教えてちょ(んじゃなぜアップできた!?という突っ込みは要りません)

 


必要なパッケージ:

php
php-devel
php-pear
php-mbstring
php-pdo (SQLite3)
php-process
PECL inotify
procps

#CentOS6でテストしていますが、他のディストリビューションでも同じようなパッケージを入れれば動くと思います。

 

使い方:

Step0. インストールしてください(例. CentOS6の場合)

yum -y install php php-devel php-pear php-mbstring php-pdo php-process
pecl install channel://pecl.php.net/inotify-0.x.x

wget 'https://github.com/disco-v8/Ban4ip/archive/master.zip' -O Ban4ip-master.zip
unzip ./Ban4ip-master.zip
cd ./Ban4ip-master/

chmod 700 ./ban4ipd
chmod 700 ./ban4ipc
chmod 755 ./init.d/ban4ip

mkdir /etc/ban4ip/
mkdir /var/lib/ban4ip/

cp ./ban4ipd.conf /etc/
cp ./ban4ip/* /etc/ban4ip/
cp ./ban4ipc /usr/bin/
cp ./ban4ipd /usr/bin/
cp ./ban4ipd_*.php /usr/bin/

cp ./logrotate.d/ban4ip /etc/logrotate.d/

cp ./init.d/ban4ip /etc/init.d/
chkconfig --add ban4ip

うまく動いたら、fail2banを動かしていた人は止めるのを忘れずに。同じような処理が走って重たくなるだけなので。

Step1. メインの設定ファイル「ban4ipd.conf」とサブ設定ファイル(/etc/ban4ip/*.conf)を設定しましょう

メイン設定ファイル…

このツールを必要としている人なら、設定ファイルを見れば理解できると思います。

    :
    :
target_service = 'apache-error'            ... ログ出力にのみ関係します(後述)
target_log = '/var/log/httpd/error_log'    ... 監視対象ログファイル名(フルパスで記述すること)
target_protcol = tcp                       ... BANするプロトコル
target_port = 80                           ... BANするポート
target_rule = 'DROP'                       ... BANする際のパケットの扱い(DROP, REJECT, LOG)

target_str[] = '/error\] \[client (.*)\] client /'        ... (.)はBANするIPアドレスが書いてある場所
    :
    :

target_str[]は配列変数です。

ここに正規表現でfailの場合のログの文字列と、BAN対象アドレスが書いてある場所を(.)で指定してください。

target_portとtarget_ruleを’all’にすると、対象IPアドレスからのすべてのアクセスをBANします。

サブ設定ファイルを新たに作ったり、既存のものを追加修正した場合には、連絡してくれると取りこみます。

みんなで幸せになりましょう。

Step2. ban4ipdを起動しましよう

ban4ipc start

もしサブ設定ファイルを変更したら

ban4ipc reload

または、メインの設定ファイルを変更したなら

ban4ipc restart

もしBANしているIPアドレスの一覧を見たいなら

ban4ipc list

その他のオプション(手動のBANやUNBAN)については

ban4ipc -h

それではよい睡眠を。:-)

 

技術メモ:

“Inotify extension not loaded!?”, but PECL inotify installed.

「extension=inotify.so」を/etc/php.d/inotify.iniなどに記述してください。

“PHP Fatal error: Class ‘SQLite3’ not found in /root/ban4ip/ban4ipd.php on line 330”

php-pdo (SQLite3)をインストールしてください。

“ban4ipd … Found other process : /var/run/ban4ip.pid!?”

前回の起動時に何らかの原因でプロセスが異常終了し、PIDファイルが残ったままです。
原因を取り除いて「/var/run/ban4ip.pid」を削除してから起動してください。

“PHP Warning: SQLite3::exec(): database is locked in …”

SQLite3のデータベースのロックが他のプロセスでかかったまま一定時間を経過してしまった場合に発生。
db_timeoutの値を伸ばしてみるといいかも。(デフォルトは500ms…これでも結構長いと思うんだけど)

 

#以下日本語だけの技術メモ

・ban4ipdは、PHPで記述されていて、プロセスのフォークによりデーモンとして動作します。
・logrotateによる監視対象ファイルの切り詰めに対応しています。(inotifyでIN_MOVE_SELFを監視)
・一つのtcpポートに対して複数の設定ファイルを置くことはできますが、iptablesの設定はポート単位となります。
(fail2banは、一つの設定ファイルごとにチェインを作る感じだった(確実にそうではない)が、ban4ipではそこまで求めていない)

 

ライセンス:

Copyright (c) 2016, Future Versatile Group
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met: Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
Neither the name of the “Future Versatile Group” nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS
IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

T.Kabu/MyDNS.JP

□VineLinux6でBan4ipのインストール

$
0
0

インストールの仕方だけ、だらだらと…

apt-get -y install php5 php5-devel php5-pear php5-pdo php5-pcntl
pecl install channel://pecl.php.net/inotify-0.1.6

cat > /etc/php5/php.d/pcntl.ini # or Edit and remove ";"

--------------------------------
extension=pcntl.so
--------------------------------

cat > /etc/php5/php.d/inotify.ini

--------------------------------
extension=inotify.so
--------------------------------

cd /usr/src/package/
wget 'https://github.com/disco-v8/Ban4ip/archive/master.zip' -O Ban4ip-master.zip
cd /usr/src/
unzip ./package/Ban4ip-master.zip

cd ./Ban4ip-master/

chmod 700 ./ban4ipd
chmod 700 ./ban4ipc
chmod 755 ./init.d/ban4ip

mkdir /etc/ban4ip/
mkdir /var/lib/ban4ip/

/bin/cp ./ban4ipd.conf /etc/
/bin/cp ./ban4ip/* /etc/ban4ip/
/bin/cp ./ban4ipc /usr/bin/
/bin/cp ./ban4ipd /usr/bin/
/bin/cp ./ban4ipd_*.php /usr/bin/

/bin/cp ./logrotate.d/ban4ip /etc/logrotate.d/

/bin/cp ./init.d/ban4ip /etc/init.d/
chkconfig --add ban4ip

/usr/bin/fail2ban-client stop
rm -rf /var/lib/fail2ban/fail2ban.sqlite3
/etc/init.d/ban4ip start

tail -F /var/log/ban4ipd.log

□CentOS7でBan4ipのインストール

$
0
0

またまたやり方だけダラダラと…

yum -y install php php-devel php-pear php-mbstring php-pdo php-process
pecl install channel://pecl.php.net/inotify-0.1.6

cat > /etc/php.d/inotify.ini

--------------------------------
extension=inotify.so
--------------------------------

mkdir /usr/src/package
cd /usr/src/package/
wget 'https://github.com/disco-v8/Ban4ip/archive/master.zip' -O Ban4ip-master.zip
cd /usr/src/
unzip ./package/Ban4ip-master.zip

cd ./Ban4ip-master/

chmod 700 ./ban4ipd
chmod 700 ./ban4ipc
chmod 755 ./init.d/ban4ip

mkdir /etc/ban4ip/
mkdir /var/lib/ban4ip/

/bin/cp ./ban4ipd.conf /etc/
/bin/cp ./ban4ip/* /etc/ban4ip/

/bin/cp ./ban4ipc /usr/bin/
/bin/cp ./ban4ipd /usr/bin/
/bin/cp ./ban4ipd_*.php /usr/bin/

/bin/cp ./logrotate.d/ban4ip /etc/logrotate.d/

/bin/cp ./systemd/ban4ip.service /usr/lib/systemd/system/
systemctl daemon-reload
systemctl status ban4ip

systemctl enable ban4ip
systemctl status ban4ip

emacs /etc/ban4ipd.conf

systemctl stop fail2ban
rm -rf /var/lib/fail2ban/fail2ban.sqlite3

systemctl start ban4ip
systemctl status ban4ip

tail -F /var/log/ban4ipd.log

□FreeRADIUSでradutmpベース(というか、NASを参照しない)での同時接続制限(Simultaneous-Use := 1)

$
0
0

タイトルは長いが、まぁやりたいことを書くとこういう事。

FreeRADIUSで「同時接続制限(Simultaneous-Use := 1)」(のテスト)をしようとすると
checkrad(Perlのスクリプト)が呼び出されて、その結果によりOK/NGを返すわけだが、
当然実機がないと(もしくは実機にアクセスできないと)、テストができない。

で、処理の流れ的にclient.confにnas_typeをいろいろ書かないと、そもそも同時接続
制限はできないということになっている。

radiusd -Xで起動して、処理の流れを見ると判るが、

--------------------------------
	:
(0) # Executing section session from file /etc/raddb/sites-enabled/default
(0)   session {
(0)  radutmp : EXPAND /var/log/radius/radutmp
(0)  radutmp :    --&gt; /var/log/radius/radutmp
(0)  radutmp : EXPAND %{User-Name}
(0)  radutmp :    --&gt; USER-ID
checkrad: No NAS type, or type "other" not checking
(0)   [radutmp] = fail
(0)  } #  session = fail
	:
--------------------------------

ということで、NASタイプが設定されていないか、otherになっていると、チェックを
しない。

まぁ確かにradutmpの情報が正しいかどうかは疑わしいところだし、RADIUSを複数台
動かしておく場合には接続情報をどこで保持するのか、ということになるのであれだ
けどね。

まぁその辺「テストがしたい」と割り切るのであれば、checkradを適当にいじればいい。

checkradの最後の方を見ると、

--------------------------------
	:
} elsif ($ARGV[0] eq 'dot1x'){
        $ret = &amp;dot1x_snmp;
} elsif ($ARGV[0] eq 'other') {
        $ret = 1;
} else {
        print LOG "  checkrad: unknown NAS type $ARGV[0]\n" if ($debug);
        print STDERR "checkrad: unknown NAS type $ARGV[0]\n";
        $ret = 2;
}
	:
--------------------------------

というように、第一引数($ARGV[0])によりいろいろ処理しているが、otherの場合は
1を返すようになっているのに、そもそもfreeRADIUS自体の方でotherなら同時接続の
チェックをしないようになっているのだからなぁ…

というわけで、ここに

--------------------------------
	:
} elsif ($ARGV[0] eq 'dot1x'){
        $ret = &amp;dot1x_snmp;
} elsif ($ARGV[0] eq 'other') {
        $ret = 1;
} elsif ($ARGV[0] eq 'simltest') {
        $ret = 1;
} else {
        print LOG "  checkrad: unknown NAS type $ARGV[0]\n" if ($debug);
        print STDERR "checkrad: unknown NAS type $ARGV[0]\n";
        $ret = 2;
}
	:
--------------------------------

とか追加してみる。もちろんclient.confにも

--------------------------------
client localhost {
        ipaddr = 127.0.0.1
        secret = gotorun
        nas_type = simltest
}
--------------------------------

としてみる。

これで、誰かが接続している状態を作り出して、

cat > /test_login

--------------------------------
Acct-Status-Type = Start
Acct-Session-Id = 1111111111
User-Name = USER-ID
NAS-Port = 1
Framed-IP-Address = 1.1.1.1
Caller-Id = 1111111111
--------------------------------

radclient -x -f ./test_login localhost acct gotorun

radlastで

--------------------------------
USER-ID 001:localhos 1.1.1.1          Tue Jun  7 11:41   still logged in
--------------------------------

接続中である状態になっていることを確認したら、別途radtestで

radtest USER-ID PASSWORD localhost 1 gotorun

としてみると…

--------------------------------
	:
(1) # Executing section session from file /etc/raddb/sites-enabled/default
(1)   session {
(1)  radutmp : EXPAND /var/log/radius/radutmp
(1)  radutmp :    --&gt; /var/log/radius/radutmp
(1)  radutmp : EXPAND %{User-Name}
(1)  radutmp :    --&gt; USER-ID
(1)   [radutmp] = fail
(1)  } #  session = fail
(1) Login OK: [USER-ID/PASSWORD] (from client localhost port 1)
	:
--------------------------------

と、radutmp(session)としてはfailなのに、Login OKとなってしまう。

これにはからくりがあり、中の人が

http://freeradius.1045715.n5.nabble.com/Trying-to-restrict-simultaneous-use-td5739700.html

で、「Because it’s fail-safe.」とか言ってしまっている。

いやね、fail-safeにする必要ないのだけど(同時接続制限の動作確認したいから)、
そのための設定とか作ってくれよ。

というのも、該当部分のソースを確認すると、

/usr/src/freeradius-server-3.0.4/src/main/modules.c

--------------------------------
	:
#ifdef WITH_SESSION_MGMT
/*
 *      See if a user is already logged in.
 *
 *      Returns: 0 == OK, 1 == double logins, 2 == multilink attempt
 */
int process_checksimul(int sess_type, REQUEST *request, int maxsimul)
{
        rlm_rcode_t rcode;

        if(!request-&gt;username)
                return 0;

        request-&gt;simul_count = 0;
        request-&gt;simul_max = maxsimul;
        request-&gt;simul_mpp = 1;

        rcode = indexed_modcall(RLM_COMPONENT_SESS, sess_type, request);

        if (rcode != RLM_MODULE_OK) {
                /* FIXME: Good spot for a *rate-limited* warning to the log */
                return 0;
        }

        return (request-&gt;simul_count &lt; maxsimul) ? 0 : request-&gt;simul_mpp;
}
#endif
	:
--------------------------------

で、indexed_modcall()でいろいろな(radutmp意外にもsqlとかでも)、とにかく
RLM_MODULE_OK(=2)以外が返ってきたとしても「return 0;」、つまりOKを返して
しまっている。

※ちなみにradutmpで同時接続が確認されたときのrcodeは1で、RLM_MODULE_OK(=2)
とは明らかに異なっている。

これはなぁ…。

ちなみにこれを調査しているときの最新?のVer.3.0.11のソースを見てみると、

/usr/src/freeradius-server-3.0.11/src/main/modules.c

--------------------------------
	:
#ifdef WITH_SESSION_MGMT
/*
 *      See if a user is already logged in.
 *
 *      Returns: 0 == OK, 1 == double logins, 2 == multilink attempt
 */
int process_checksimul(int sess_type, REQUEST *request, int maxsimul)
{
        rlm_rcode_t rcode;

        if(!request-&gt;username)
                return 0;

        request-&gt;simul_count = 0;
        request-&gt;simul_max = maxsimul;
        request-&gt;simul_mpp = 1;

        rcode = indexed_modcall(MOD_SESSION, sess_type, request);

        if (rcode != RLM_MODULE_OK) {
                /* FIXME: Good spot for a *rate-limited* warning to the log */
                return 0;
        }

        return (request-&gt;simul_count &lt; maxsimul) ? 0 : request-&gt;simul_mpp;
}
#endif
	:
--------------------------------

同じかよ!!

というわけで、「modules.c」の問題のところを

--------------------------------
	:
#ifdef WITH_SESSION_MGMT
/*
 *      See if a user is already logged in.
 *
 *      Returns: 0 == OK, 1 == double logins, 2 == multilink attempt
 */
int process_checksimul(int sess_type, REQUEST *request, int maxsimul)
{
        rlm_rcode_t rcode;

        if(!request-&gt;username)
                return 0;

        request-&gt;simul_count = 0;
        request-&gt;simul_max = maxsimul;
        request-&gt;simul_mpp = 1;

        rcode = indexed_modcall(RLM_COMPONENT_SESS, sess_type, request);

///        if (rcode != RLM_MODULE_OK) {
///                /* FIXME: Good spot for a *rate-limited* warning to the log */
///                return 0;
///        }

        return (request-&gt;simul_count &lt; maxsimul) ? 0 : request-&gt;simul_mpp;
}
#endif
	:
-------------------------------- 

とコメントアウトしてradiusdを作り直せば、ちゃんと同時接続制限が効く。

皆さん、できないできないっていうけどオープンソースなのでソース見てくださいねー。

(っていうか、fail-safeのON/OFFをするパラメータを用意してくれ、Alan DeKokさん…あー疲れた)

□FreeRADIUSでSQLベースでの同時接続制限(Simultaneous-Use := 1)

$
0
0

前の投稿を参照すること!!

FreeRADIUSでSQLベースでの同時接続制限(Simultaneous-Use := 1)をしようとしたら、どうしてもうまくいかない。

手順としては

・MySQL(MariaDB)のインストール
・FreeRADIUS用のDBの設定
・FreeRADIUS用のDBにテーブルの設定
・FreeRADIUSのsqlモジュールを有効化&設定

なのだが、

/etc/raddb/sites-enabled/default
/etc/raddb/sites-enabled/inner-tunnel

などでsqlだけにすれば同時接続制限ができる…と言いたいところだが、これだと問題が発生する。

Alan DeKokも「Because it’s fail-safe.」と言っているように、何らかの理由でFreeRADIUSに切断情報(Acct-Status-Type = Stop)が来ない時があるからなのだが、まぁそういう時には既存の接続中という情報をradzapで削除すればいいんだけど、sqlだけにするとradzapが使えなくなる。

なぜかというと、sqlだけにするとradutmpが出力されないのでradwhoが使えない。
でもって、radzapは単なるシェルスクリプトで、中では

radwho -ZR $RADDB $NAS_IP_ADDR $NAS_PORT $USER_NAME | radclient $DEBUG $RADDB -f - $SERVER acct $SECRET

こんなコマンドを発行しているだけ。

何をしているかというと、radwho -ZR USER-IDで、

--------------------------------
User-Name = "USER-ID"
Acct-Session-Id = "11111111"
Acct-Status-Type = Stop
NAS-IP-Address = 127.0.0.1
NAS-Port = 1
Service-type = Login-User
Framed-IP-Address = 1.1.1.1
Acct-Session-Time = 23
Calling-Station-Id = "1111111111"
--------------------------------

のような出力を得たら、それをそのままradclientを使ってFreeRADIUSに投げているだけなのだが、sqlだけを有効にするとradwhoがそもそも情報を取得できない(こいつはSQLを見ていない)ので、radzapもできない、というわけ。

じゃあ、というわけでradutmpとsqlと併用すればいいのだけれど、rlm_sqlにさらなる問題がある。

実は上記のセッション情報は、

cat > /test_login

--------------------------------
Acct-Status-Type = Start
Acct-Session-Id = 1111111111
User-Name = USER-ID
NAS-Port = 1
Framed-IP-Address = 1.1.1.1
Caller-Id = 1111111111
--------------------------------

radclient -x -f ./test_login localhost acct gotorun

で接続中にした情報だが、「Acct-Session-Id」に注目してもらいたい。

そう…こちら(つまりNAS)はセッションIDとして10文字をFreeRADIUSに投げたのに、radwhoで取得したセッションIDは8文字しかない。

もしかしてRFC?とか思って調べたけど、もちろん8文字までなんて言う制限はない。
(4文字以上にしろ、とはある)

しかも、FreeRADIUSのサイトでも

http://freeradius.org/rfc/acct_session_id_uniqueness.html

ここに書いてあるけど…8文字から64文字までにしろ、でないと動作が怪しくなるかもしれない、って…

で結論から言うと、勝手にセッションIDを短くしているのは

radwho

だった。ソースを見ると、

/usr/src/freeradius-server-3.0.4/src/main/radwho.c

--------------------------------
	:
int main(int argc, char **argv)
{
        CONF_SECTION *maincs, *cs;
        FILE *fp;
        struct radutmp rt;
        char othername[256];
        char nasname[1024];
        char session_id[sizeof(rt.session_id)+1];
	:
--------------------------------

ふむ…で、この「rt.session_id」(つまり「struct radutmp rt」)は?というと

/usr/src/freeradius-server-3.0.4/src/include/radutmp.h

--------------------------------
struct radutmp {
  char login[32];               /* Loginname */
                                /* FIXME: extend to 48 or 64 bytes */
  unsigned int nas_port;        /* Port on the terminal server (32 bits). */
  char session_id[8];           /* Radius session ID (first 8 bytes at least)*/
                                /* FIXME: extend to 16 or 32 bytes */
  unsigned int nas_address;     /* IP of portmaster. */
  unsigned int framed_address;  /* SLIP/PPP address or login-host. */
  int proto;                    /* Protocol. */
  time_t time;                  /* Time entry was last updated. */
  time_t delay;                 /* Delay time of request */
  int type;                     /* Type of entry (login/logout) */
  char porttype;                /* Porttype (I=ISDN A=Async T=Async-ISDN */
  char res1,res2,res3;          /* Fills up to one int */
  char caller_id[16];           /* Calling-Station-ID */
  char reserved[12];            /* 3 ints reserved */
};
--------------------------------

セッションIDを8文字に制限しているのは、お・ま・え・か・!!

…( ゚д゚)ハッ!

ここで賢明な人は気が付いただろう…つまるところFreeRADIUSでは

 『FIXME』なところは各自変更した方がいいかもよ?

ということ。つまり、パッケージを落としてきてそのまま希望通りに動いたらラッキーなわけで、実際にはバイナリを作り直さないといけない、という話だ。

すでに同時接続制限での件もあるし、NASによってはセッションIDが8文字より大きい場合もあるだろう。

やれやれ…┐(´д`)┌ヤレヤレ

※自分はsrc.rpmをゴニョりますけどね。


□VineLinux用のcertbot-autoのパッチ(と作業)

$
0
0

Let’s EncryptのパッケージがGithubからのD/L方式になってから、VineLinuxで
動かなくなってしまった。

cd /usr/sbin/
git clone https://github.com/certbot/certbot

cd /usr/sbin/certbot

./certbot-auto

とやってみても

Sorry, I don't know how to bootstrap Certbot on your operating system!

You will need to bootstrap, configure virtualenv, and run pip install manually.
Please see https://letsencrypt.readthedocs.org/en/latest/contributing.html#prerequisites
for more info.

なんで?と思って調べてみると、インストールされているパッケージを調べる
処理でどのディストリビューションにも該当しないから…(´Д`)ハァ。

/usr/sbin/certbot/certbot-auto

の中身を見てみると、

	:
# Install required OS packages:
Bootstrap() {
  if [ -f /etc/debian_version ]; then
    echo "Bootstrapping dependencies for Debian-based OSes..."
    BootstrapDebCommon
  elif [ -f /etc/mageia-release ] ; then
    # Mageia has both /etc/mageia-release and /etc/redhat-release
    ExperimentalBootstrap "Mageia" BootstrapMageiaCommon
  elif [ -f /etc/redhat-release ]; then
    echo "Bootstrapping dependencies for RedHat-based OSes..."
    BootstrapRpmCommon
  elif [ -f /etc/os-release ] && `grep -q openSUSE /etc/os-release` ; then
    echo "Bootstrapping dependencies for openSUSE-based OSes..."
    BootstrapSuseCommon
  elif [ -f /etc/arch-release ]; then
    if [ "$DEBUG" = 1 ]; then
      echo "Bootstrapping dependencies for Archlinux..."
      BootstrapArchCommon
    else
      echo "Please use pacman to install letsencrypt packages:"
      echo "# pacman -S certbot certbot-apache"
      echo
      echo "If you would like to use the virtualenv way, please run the script again with the"
      echo "--debug flag."
      exit 1
    fi
  elif [ -f /etc/manjaro-release ]; then
    ExperimentalBootstrap "Manjaro Linux" BootstrapArchCommon
  elif [ -f /etc/gentoo-release ]; then
    ExperimentalBootstrap "Gentoo" BootstrapGentooCommon
  elif uname | grep -iq FreeBSD ; then
    ExperimentalBootstrap "FreeBSD" BootstrapFreeBsd
  elif uname | grep -iq Darwin ; then
    ExperimentalBootstrap "Mac OS X" BootstrapMac
  elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then
    ExperimentalBootstrap "Amazon Linux" BootstrapRpmCommon
  elif [ -f /etc/product ] && grep -q "Joyent Instance" /etc/product ; then
    ExperimentalBootstrap "Joyent SmartOS Zone" BootstrapSmartOS
  else
    echo "Sorry, I don't know how to bootstrap Certbot on your operating system!"
    echo
    echo "You will need to bootstrap, configure virtualenv, and run pip install manually."
    echo "Please see https://letsencrypt.readthedocs.org/en/latest/contributing.html#prerequisites"
    echo "for more info."
    exit 1
  fi
}
	:

となっているが、ここのどのディストリビューションにも該当しない。

させようとして

/etc/debian_version (→ BootstrapDebCommon)

とか

/etc/redhat-release (→ BootstrapRpmCommon)

を置いても、それぞれのディストリビューション用のコマンド(dpkgとかdnf,yum)がないのでエラーとなる。

というわけで、VineLinuxように同じ処理を追加(パッチ)してみる。

BootstrapRpmCommonの処理を見ると、手っ取り早くは、

	:
  pkgs="
    gcc
    dialog
    augeas-libs
    openssl
    openssl-devel
    libffi-devel
    redhat-rpm-config
    ca-certificates
  "
	:
    pkgs="$pkgs
      python27
      python27-devel
      python27-virtualenv
      python27-tools
      python27-pip
    "

このあたりのパッケージがあればいい。

ただし、augeas-libsに関するパッケージはないので手動インストールしないといけない。
(インストールする際にはlibxml2-develが必要)

apt-get -y install libxml2-devel
mkdir /usr/src/package
cd /usr/src/package
wget http://download.augeas.net/augeas-1.5.0.tar.gz
cd ../
tar xvzf package/augeas-1.5.0.tar.gz
cd augeas-1.5.0/
./configure --prefix=/usr
make
make install
ldconfig
ldconfig -p | grep libaugeas

さらに、certbot-autoは内部の処理でpipの古いバージョン(8.0.3)を落としてくるのだが、
新しいバージョンがあると(現に8.1.2があるけど)「pipが古いからアップグレードしろ」と
メッセージがでる。

でも、certbot-autoによるパッケージのインストール自体を仮の環境で実行しているので、
certbot-autoの内部処理でアップグレードを実行するにしないといけない。

cp /usr/sbin/certbot/certbot-auto /usr/sbin/certbot/certbot-auto.org
emacs /usr/sbin/certbot/certbot-auto

	:
	:
BootstrapVineCommon() {
  # Tested with:
  #   - Vine Linux 6.3

  if type apt-get 2>/dev/null
  then
    tool=apt-get

  else
    echo "Neither apt-get found. Aborting bootstrap!"
    exit 1
  fi

  pkgs="
    gcc
    dialog
    openssl
    openssl-devel
    mod_ssl-apache2
    libffi-devel
    rpm-utils
    ca-certificates
    python27
    python27-devel
    python27-tools
    python-virtualenv
  "

  if [ "$ASSUME_YES" = 1 ]; then
    yes_flag="-y"
  fi

  if ! $SUDO $tool install $yes_flag $pkgs; then
      echo "Could not install OS dependencies. Aborting bootstrap!"
      exit 1
  fi
}
	:
	:
  elif [ -f /etc/vine-release ]; then
    echo "Bootstrapping dependencies for VineLinux..."
    BootstrapVineCommon
	:
	:
def main():
    temp = mkdtemp(prefix='pipstrap-')
    try:
        downloads = [hashed_download(url, temp, digest)
                     for url, digest in PACKAGES]
        check_output('pip install --upgrade pip; ' +
                     'pip install --no-index --no-deps -U ' +
                     ' '.join(quote(d) for d in downloads),
                     shell=True)
	:
	:

※Python2.6でも、やろうと思えばできるけど、2.7の方がいいと思う。

diff -up /usr/sbin/certbot/certbot-auto.org /usr/sbin/certbot/certbot-auto > \
/usr/sbin/certbot/vine-certbot-auto.patch

これで以下のようなパッチができるので、実際はこれを当ててくれればOK。

cat > /usr/sbin/certbot/vine-certbot-auto.patch

--- /usr/sbin/certbot/certbot-auto.org  2016-07-26 16:08:04.836061304 +0900
+++ /usr/sbin/certbot/certbot-auto      2016-07-26 16:10:55.247319519 +0900
@@ -323,6 +323,44 @@ BootstrapRpmCommon() {
   fi
 }

+BootstrapVineCommon() {
+  # Tested with:
+  #   - Vine Linux 6.3
+
+  if type apt-get 2>/dev/null
+  then
+    tool=apt-get
+
+  else
+    echo "Neither apt-get found. Aborting bootstrap!"
+    exit 1
+  fi
+
+  pkgs="
+    gcc
+    dialog
+    openssl
+    openssl-devel
+    mod_ssl-apache2
+    libffi-devel
+    rpm-utils
+    ca-certificates
+    python27
+    python27-devel
+    python27-tools
+    python-virtualenv
+  "
+
+  if [ "$ASSUME_YES" = 1 ]; then
+    yes_flag="-y"
+  fi
+
+  if ! $SUDO $tool install $yes_flag $pkgs; then
+      echo "Could not install OS dependencies. Aborting bootstrap!"
+      exit 1
+  fi
+}
+
 BootstrapSuseCommon() {
   # SLE12 don't have python-virtualenv

@@ -494,6 +532,9 @@ Bootstrap() {
   elif [ -f /etc/redhat-release ]; then
     echo "Bootstrapping dependencies for RedHat-based OSes..."
     BootstrapRpmCommon
+  elif [ -f /etc/vine-release ]; then
+    echo "Bootstrapping dependencies for VineLinux..."
+    BootstrapVineCommon
   elif [ -f /etc/os-release ] && `grep -q openSUSE /etc/os-release` ; then
     echo "Bootstrapping dependencies for openSUSE-based OSes..."
     BootstrapSuseCommon
@@ -890,7 +931,8 @@ def main():
     try:
         downloads = [hashed_download(url, temp, digest)
                      for url, digest in PACKAGES]
-        check_output('pip install --no-index --no-deps -U ' +
+        check_output('pip install --upgrade pip; ' +
+                     'pip install --no-index --no-deps -U ' +
                      ' '.join(quote(d) for d in downloads),
                      shell=True)
     except HashError as exc:

cert-botが新しくなったりしたら、これを参考にパッチ作って充てればいいかなぁ?

cd /usr/sbin/certbot/
patch < /usr/sbin/certbot/vine-certbot-auto.patch

で、インストールできたらcertbot-autoを実行すればよい。

/usr/sbin/certbot/certbot-auto -v

OKなら、

/usr/sbin/certbot/certbot-auto certonly \
--webroot --webroot-path /var/www/html -d example.jp \
--agree-tos -m 自分のメールアドレス

でさっそくドメイン認証(DV)を取得してみよう。

※ちなみにテスト用にと設定した「~.mydns.jp」はまたしても使われすぎで取得できなかった…(´Д`)ハァ…

□Debian8.5(jessie)でのBan4ipのインストール

$
0
0

実際にはARMbianで試しましたが、まぁ同じでしょう。:-)

apt-get -y install php5 php5-cli php5-common php5-dev sqlite3 php-pear php5-sqlite

cat > /etc/php5/mods-available/inotify.ini

--------------------------------
extension=inotify.so
--------------------------------

cd /etc/php5/cli/conf.d/
ln -s ../../mods-available/inotify.ini ./20-inotify.ini

mkdir /usr/src/package
cd /usr/src/package/
rm -f Ban4ip-*
wget 'https://github.com/disco-v8/Ban4ip/archive/master.zip' -O Ban4ip-master.zip
cd /usr/src/
rm -rf Ban4ip-*
unzip ./package/Ban4ip-master.zip

cd ./Ban4ip-master/

chmod 700 ./ban4ipd
chmod 700 ./ban4ipc
chmod 755 ./init.d/ban4ip

mkdir /etc/ban4ip/
mkdir /var/lib/ban4ip/

/bin/cp ./ban4ipd.conf /etc/
#/bin/cp ./ban4ip/* /etc/ban4ip/	※1

/bin/cp ./ban4ipc /usr/bin/
/bin/cp ./ban4ipd /usr/bin/
/bin/cp ./ban4ipd_*.php /usr/bin/

/bin/cp ./logrotate.d/ban4ip /etc/logrotate.d/

/bin/cp ./systemd/ban4ip.service /usr/lib/systemd/system/
systemctl daemon-reload
systemctl status ban4ip

systemctl enable ban4ip
systemctl status ban4ip

emacs /etc/ban4ipd.conf

emacs /etc/ban4ipd/			※2

systemctl start ban4ip
systemctl status ban4ip

tail -F /var/log/ban4ipd.log

※1	必要なもののみコピー
※2	認証エラーのログは/var/log/auth.logになっているので、
	confファイルのログファイル名を必要に応じて書き直し

 

□Raspberry Pi(Fedora ARM)にJBL Pebblesを繋いでみる

$
0
0

まぁ差せば認識。

> Sep 15 12:09:18 mydns-adapter kernel: usb 1-1.4: new full-speed USB device number 8 using dwc_otg
> Sep 15 12:09:18 mydns-adapter kernel: usb 1-1.4: New USB device found, idVendor=05fc, idProduct=0231
> Sep 15 12:09:18 mydns-adapter kernel: usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
> Sep 15 12:09:18 mydns-adapter kernel: usb 1-1.4: Product: JBL Pebbles
> Sep 15 12:09:18 mydns-adapter kernel: usb 1-1.4: Manufacturer: Harman Multimedia
> Sep 15 12:09:18 mydns-adapter kernel: usb 1-1.4: SerialNumber: 1.0.0
> Sep 15 12:09:18 mydns-adapter kernel: input: Harman Multimedia JBL Pebbles as /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.2/0003:05FC:0231.0007/input/input6
> Sep 15 12:09:18 mydns-adapter kernel: hid-generic 0003:05FC:0231.0007: input,hidraw3: USB HID v1.00 Device [Harman Multimedia JBL Pebbles] on usb-3f980000.usb-1.4/input2
> Sep 15 12:09:19 mydns-adapter kernel: usbcore: registered new interface driver snd-usb-audio
> Sep 15 12:09:19 mydns-adapter systemd: Reached target Sound Card.

…Linuxで普通に認識するんだから当たり前か。

ちなみにSDLでのボリューム制御はscancodeが114なら-、115なら+、でした。

 

□技適マークのないマイコンボードを国内で使うには?

$
0
0

技適マークのない機器を国内で使うと電気通信事業法や電波法に違反するのは

技適マークのない機器で無線を使っていたので自首してきた。

というサイトで有名になりました。

元々、自分みたいに無線をやっていた人は知っていたはずですけど、このサイトには自分が知りたい肝心なことが書いてありませんでした。

 
そこで、

総合通信相談所 03-6238-1940
http://www.soumu.go.jp/soutsu/kanto/ques/faq/ques/

に肝心なところを聞いてみましたよ!!

 
自分:すいません、ちょっとお尋ねしたいのですが

通相:はいなんでしょう?

自分:いわゆる技適マークのないスマホとかは国内で使うと電波法違反じゃないですか

通相:そうですねぇ

自分:そういうのの動作検証をしたいときには電波暗室とかを使うと思うんですけど、スマホじゃなくて技適マークのないマイコンボードの動作検証をするときに

通相:はいはい

自分:Wi-Fi、無線LANのチップをはがしたりすればいいんでしょうけど、それもできない場合にはいわゆる『ダミーロード』を繋いで動作させる分には問題ないんでしょうか?

通相:ええそうですね

自分:(あれ、あっさり)

通相:電波暗室が用意できない場合でも、ダミーロードを繋げられれば問題ないですよ

自分:そうなんですかー

通相:そうですね、放送局なんかも機器の動作確認をするのに電波出さずにダミーロード繋いでしたりしますし

自分:(あー、むかしむかし木更津でもそんな話を聞いたな)

自分:なるほど、自分もアマチュア無線やってるんで、無線機ならダミーロード繋げばいいのはしってましたけど、マイコンボードの場合にはどうなのかなーと思って

通相:放送局でもダミーロード使って動作確認していますし、問題ないですよ

自分:そうなんですねー、ありがとうございました!!

 
…というわけで、昨日からAliexpressの買い物かごに入っているU.FL(MHFとかIPEXと同義)からSMAへの変換コードとダミーロード(それぞれ10個)をさっそくポチっとな。 😀

10 PCS   Goldplated  SMA Male 2W 6GHZ 50 Ohm Dummy  Load Connector Plug-in Connectors

10 pcs  U.FL IPX Female to SMA Female Inner Hole Jack Pigtail Cable Jumper 10cm Connector

これだけ買っとけば、誰かさんにも分けられるしね!! 🙂

□ダミーロードが届きました(for 技適マークのないマイコンボード)

$
0
0

前回、□技適マークのないマイコンボードを国内で使うには?という投稿で書いていた通り、日本国内の電波法を遵守するために発注していたダミーロード一式が届きました。

Shipping Free(送料無料:中国郵政と日本郵政を利用する一番安い方法)で注文してから約一週間で到着です。いつもでしたら一ヶ月くらいかかったり、場合によっては二ヶ月近くかかったりするのに、えらい速いです。(笑)

で、早速検品ですが、しっかり頼んだ個数(ダミーロードと、ケーブル一式合わせて10セット)以上入っていました。

早速手持ちの、今まで置きモノだったOrangePi 2Eのアンテナ端子に繋いでみます…が、なかなか入ってくれません。まさか間違えて違うコネクタのケーブルにしてしまったかと思ったのですが、ちゃんとIPX3と見えます。

ただし、この裏の芯線が入る穴が小さいみたいです。まぁまだ一回も挿されたことがないのだろう、という事でぐりぐりやったらできました。

これでOSCなどでも電源を投入することができます。

今回のOrangePi 2Eのような技適マークのない機器でも、ダミーロードを繋けられれば問題ないとお墨付きをいただきましたので、以後の開発がはかどりそうです。(さて、でもって何を開発しよう?)

 

□中華系通販サイト(アリババじゃないョ)での返金手続きについて

$
0
0

以前よりAliExpressはよく使っているのですが、先日ツイッターで「高橋敏也の改造バカ一台」で有名な高橋さんが「https://www.wish.com/」という通販サイトをAKIBA!PCホットラインで紹介していたので見てみたところ、かなりアヤシイ値段で売っているのでさっそくいくつかをポチって見ました。

ちょうどワイヤレスイヤホンが欲しかったので、安いこともありいくつかポチったのですが、これは日本円で2,000円くらい出さないと性能というか品質というかが納得できないなと思いました。まー動くんですけどね、再生周波数範囲が狭いっぽいとか、プラスチッキーというか、ね…。1,000円以下に求めるなという話もありますが、ちゃんと鳴るだけましなんでしょうけど。(笑)

(これはそれなりに満足したワイヤレスイヤホンです)

で、リアにもドライブレコーダーが欲しいなぁ、ついでにいい感じだったらフロントも今のアクションカムから置き換えたいなー、と思って、1,000円以下の激安ドライブレコーダーをポチって見ましたところ、これがワイヤレスイヤホンとは違って全然求める性能ではないので、文句を言って返金手続きをしてもらったので、そのやり取りを記しておきたいと思います。

モノとしてはちゃんと動きそうに見えますし、実際にドライブレコーダーの機能としては問題ないのですが、いかんせん画角が狭すぎです。

これではどう見ても30度くらいしかありませんので、さっそくwishのサイトの『注文履歴』から『サポートへの問い合わせ』を選択し、『返品と返金』から『返金を要求』を選択して、『アイテムが説明どおりに使えません』としてから、

This lens is not 170 deg!
It is 30-45 deg!
I was deceived?

とメッセージ(質問)を送りました。

すると、数日後に

… will you kindly send the whole photo of the actual item you received (not from Wish Website or any online sites) and a photo showing any issue or defect of the item (if applicable)?

(受け取った実際の商品(Wishウェブサイトやオンラインサイトからではありません)の全写真と商品の問題や欠点を示す写真(該当する場合)をお送りしますか?)

と返事が来ましたので、以下のような写真とともに、改めて同様の手続きで写真を添付して送りました。

さすがにここまで画像に説明をつけて送れば、向こうもわかってくれるだろう、と思っていたら翌日にはすぐに返金手続きをするよ、ということで返事がありました。

Thank you for letting us know about this and I’m sorry to hear that the item you received did not work as described. The camera isn’t wide angle as to what I’ve seen on the photo you have provided. We regret that this has slipped past our quality measures. We will let the store know so they can review the item.

I’ve gone ahead and refunded this for you as your satisfaction is our top priority and we only want what’s best for you.

It’ll reflect back to your original form of payment in as fast as 5-10 business days. Good news is, we’ll no longer require you to return the item, and you may keep it for your convenience.

Hope I was able to provide a quick resolution on this and please let us know should you have other inquiries and we’re more than happy to help you right away!

May you have an awesome day! 🙂

(私達にこれを知らせてくれてありがとうと、あなたが受け取ったアイテムが説明どおりに動かなかったと聞いて申し訳ありません。カメラはあなたが提供した写真で見たように広角ではありません。これが私たちの品質基準を過ぎてしまったことは残念です。店舗に知らせて、商品をレビューできるようにします。

あなたの満足度が最優先事項であるため、私は先に進み、あなたのためにこれを払い戻しました。私たちはあなたにとって最良のものだけを求めています。

5~10営業日以内に元のお支払い方法に反映されます。良いニュースは、もはやあなたが商品を返品する必要がなくなり、あなたの便宜のためにそれを保管することです。

私はこれについて迅速な解決策を提供することができたと思います。他のお問い合わせがあればお知らせください。すぐにお手伝いします!

あなたは素晴らしい一日を過ごせますか? 🙂 )

 

で、実際Paypalに速攻で【商品代金】が返金されました。
高橋さんが紹介していたようにPaypal払いにしといてよかった。

送料については返ってこないけど、でもまぁ送り返さなくてもいいのだから、まぁいいか。
(とはいえ画角が30度のドライブレコーダー、というかカメラなんて何の使い道もないからなぁ…)

 

以上、アヤシクない中華系通販サイト(アリババじゃないョ)での返金手続きについてでした。

□OrangePiを、USB-OTGを使って、T〇SHIBAのRE〇ZAのUSB接続機器にする

$
0
0

昨年、ついに我が家にもテレビ(東芝のREGZA)が来た!

家のLAN環境を大幅に改善して、といってもLANケーブルを各部屋に配線したくらいだけど、ストレージサーバーを作ろうと目論んでいた。

が、最近のREGZA(だけじゃないのかな?)はいわゆるNAS(sambaとか)に録画できない、という情報を村役場で得ました。(Thanks @nogisawa)

家に帰って説明書を読むと、たしかに最近のはできないらしい。以前のはできたのに!なんというデグレードだ!

…しょうがない、ストレージサーバーはあきらめてUSB接続もできるNASにするか、と、途方に暮れていた。

でもよく考えると、このストレージサーバーって中身がLinuxじゃないの???

つまるところ、Raspberry Pi(RasPi)みたいなのでUSBストレージもどきにして、そこに録画できるのでは?と思いついた。

その後いろいろ調べてみると、USB OTG(USB On-The-Go)という機能を使うことで、RasPiをUSBストレージにするという記事(※)をいくつか見つけることができた。

Raspbianでということならば、Orange Pi(OPi)にArmbianでもできるだろう、と調べ続けていたら、さすが鹿児島LUG(KagoLUG)の@matokenさんの記事(※)も見つけることができた。(これたぶん昔見たはずだ…)

[メモ] Raspberry Pi ZeroをUSBマスストレージデバイスとして使う 
*PiをUSBゲームパッドとして動作させる 

Raspberry PiのUSB OTGを試す 

RasPiの場合にはZEROでないとUSB-OTGがないが、速度を考えるとRasPi3とかの方がいいだろうなー、と思って調べてみたら、USB-OTGがついているのはLANポートがないタイプ(AとかZERO)しかないらしい。

さすがにどっちも持っていないので、買ったけど積んで放置していたOrange Pi(OPi)のPlus 2E(Opi2E)を使うことにする。

OPiもUSB-OTGが付いているのと付いていないのがあるが、手持ちのOpi2EはOTG対応のUSBポートが一つある。(ま、OPiの場合にはUSB-OTG以外にWiFiの有無、という技適問題があるんだけどね)

というわけで、今回はOPi用のArmbianを使って、USB-OTG機能を有効にして、OPiの接続機器からはUSBストレージとして見えるように構築してみる。

・Armbian

https://dl.armbian.com/

にいろいろなマイコンボート用のArmbianがある中から、OPi2E用のArmbianを落としてくる。

SDスロットがあるLinuxマシンで(Windowsでもいいけど、やることは落としてきたイメージを展開してmicroSDに焼けばいいだけだし…)

mkdir /usr/src/package
cd /usr/src/package
wget https://dl.armbian.com/orangepiplus2e/archive/Armbian_5.35_Orangepiplus2e_Debian_jessie_default_3.4.113.7z
7z x ./Armbian_5.35_Orangepiplus2e_Debian_jessie_default_3.4.113.7z

ダウンロードしてきたら、microSDを挿して

cd ~
umount /dev/mmcblk0p*

dd if=/usr/src/package/Armbian_5.35_Orangepiplus2e_Debian_jessie_default_3.4.113.img of=/dev/mmcblk0 bs=512M

そしたらArmbianのデフォルトパスワード「root/1234」でログインしてrootのパスワードを新しくする。

さらに新しいユーザーとそのパスワードを設定。

で、簡単にArmbianの設定。

・ディスプレイモードの変更

h3disp -m 32

とかで1024×768のディスプレイモードになる。(1920×1200はない)

・eMMCにコピー。

OPi2Eは16GBのeMMCが搭載されている。(読み書き速度は50MB/s以上出るよ!!)
microSDからの起動はかったるいのでeMMCにコピーしてしまう。

armbian-config

で、 System→Install→eMMCにコピー

・タイムゾーンも日本(JST)に

さらに、Personal→Timezone→ASIA/Tokyo、で日本時間にする。

他にも、いろいろ設定できるけど、とりあえず肝心の設定に進むのでarmbian-configを抜ける。

・最新のシステムにバージョンアップ

apt-get -y update;apt-get -y upgrade

・日本語化

…は、しない方がいいかな?表示が字化けても嫌だし。:-)

やりたい人は

apt-get -y install language-pack-ja-base language-pack-ja ibus-mozc
localectl set-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"
source /etc/default/locale
echo $LANG

ちなみにGUIも入れるならそっちもそっちで変更が必要なので、めんどい。(笑)

・本題のUSB-OTG化

カーネルのUSBガジェットモジュールを見てみると、

ls -al /lib/modules/3.4.113-sun8i/kernel/drivers/usb/gadget

> -rw-r–r– 1 root root 31292 Nov 22 21:45 dummy_hcd.ko
> -rw-r–r– 1 root root 29488 Nov 22 21:45 gadgetfs.ko
> -rw-r–r– 1 root root 43740 Nov 22 21:45 g_audio.ko
> -rw-r–r– 1 root root 65076 Nov 22 21:45 g_cdc.ko
> -rw-r–r– 1 root root 68724 Nov 22 21:45 g_ether.ko
> -rw-r–r– 1 root root 39804 Nov 22 21:45 g_hid.ko
> -rw-r–r– 1 root root 60836 Nov 22 21:45 g_mass_storage.ko
> -rw-r–r– 1 root root 114572 Nov 22 21:45 g_multi.ko
> -rw-r–r– 1 root root 51436 Nov 22 21:45 g_ncm.ko
> -rw-r–r– 1 root root 30040 Nov 22 21:45 g_printer.ko
> -rw-r–r– 1 root root 54176 Nov 22 21:45 g_serial.ko
> -rw-r–r– 1 root root 40208 Nov 22 21:45 g_zero.ko

肝心の「g_mass_storage.ko」がある。

とりあえず2GB程度のストレージ領域イメージファイルをeMMCに作る。

dd if=/dev/zero of=/var/tmp/test.img bs=1M count=2048

そして、このストレージ領域イメージファイルにfdiskでパーティションを作成して、typeをcにしてVFATにする。

fdisk /var/tmp/test.img

VFATにしたら、ループバックデバイスとしてマウントしてフォーマットする。

losetup -o 1024k /dev/loop0 /var/tmp/test.img
mkfs.vfat /dev/loop0
losetup -d /dev/loop0
sync
sync
sync

これでストレージ領域イメージファイルの準備ができたので、「g_mass_storage.ko」モジュールを使ってUSBストレージにする。

rmmod g_mass_storage
modprobe g_mass_storage file=/var/tmp/test.img stall=0

※stall=0がポイント、で、echo 2することで有効になる。

で、dmesgすると、

> [ 101.822392] usb open backing file: /var/tmp/test.img, 0xee495400
> [ 101.822767] g_mass_storage gadget: Mass Storage Function, version: 2009/09/11
> [ 101.822810] g_mass_storage gadget: Number of LUNs=1
> [ 101.822883] lun0: LUN: removable file: /var/tmp/test.img
> [ 101.822960] ep_matches, wrn: endpoint already claimed, ep(0xc09791ac, 0xbf210c1c, ep1in-bulk)
> [ 101.823023] g_mass_storage gadget: Mass Storage Gadget, version: 2009/09/11
> [ 101.823073] g_mass_storage gadget: userspace failed to provide iSerialNumber
> [ 101.823137] g_mass_storage gadget: g_mass_storage ready

となって、準備完了。

OPi2EのOTG対応USBはmicroUSBポートなので、ここにUSBケーブルをさして、まずはPCなどにつないでみるといい。

> [ 125.343731] g_mass_storage gadget: high-speed config #1: Linux File-Backed Storage

OPi2E側ではこのようになって、PC側でもストレージが現れる!

ただし、PC側でアンマウントしても、OPi2E側では何も出てこない。

ケーブルを抜いても何もならない。もう一度ケーブルをさすと、またPC側でストレージが現れ、OPi2E側でも

> [ 285.319586] g_mass_storage gadget: high-speed config #1: Linux File-Backed Storage

となって、また認識するだけ。

あとはディスクベンチマークソフト(CrystalDiskMarkとか)で、ひとまずeMMCでの性能測定をしてみる。


eMMCを対象に50MBでテスト


eMMCを対象に1GBでテスト

だいたい20MB/s(160Mbps)くらい出ているのが判る。

@nogisawa 君曰く

「1つの録画で必要な帯域は多めに見積もっても30Mbps余裕だと思う」
USB 2.0の実測値って感じの速度な気がする」

ということなので、これでいいらしい。

・ストレージはNFSに

参考:https://www.server-world.info/query?os=Debian_8&p=nfs&f=2

本来の目標はネットワークでつながったストレージサーバーを構築したい。

なので、OPi2Eはあくまで「USB←→LANストレージコンバーター」的な役割をしてもらう。
そして実際のストレージは、OPi2EのArmbianからみてNFSでマウントした、ネットワーク上の別のNFSサーバーのストレージとする。

はたしてNFSサーバーのストレージの速度は、録画の書き込み速度に間に合うのか!?

というわけで、まずはNFSサーバーを用意して、Armbianからマウントしてみる。

apt-cache search nfs
apt-get -y install nfs-common nfstest
mkdir /stock
mount -t nfs4 192.168.192.123:/ /stock -o hard,intr
df -h

> Filesystem Size Used Avail Use% Mounted on
> /dev/mmcblk0p1 15G 3.1G 11G 23% /
> udev 10M 0 10M 0% /dev
> tmpfs 403M 5.6M 398M 2% /run
> tmpfs 1008M 0 1008M 0% /dev/shm
> tmpfs 5.0M 4.0K 5.0M 1% /run/lock
> tmpfs 1008M 0 1008M 0% /sys/fs/cgroup
> tmpfs 1008M 0 1008M 0% /tmp
> log2ram 50M 2.7M 48M 6% /var/log
> tmpfs 202M 0 202M 0% /run/user/0
> 192.168.192.123:/ 16G 4.2G 11G 29% /stock

というように、NFSサーバーのストレージがNFSでマウントできたので、いざ速度を測定してみる。

apt-get -y install fio
fio --name=/stock/fiodiskmark --rw=randread --size=50m --name=job1

> READ: io=51200KB, aggrb=8017KB/s, minb=8017KB/s, maxb=8017KB/s, mint=6386msec, maxt=6386msec

50MBの読み込みで実質8MB/s!?…遅くない?

fio --name=/stock/fiodiskmark --rw=randread --size=1024m --name=job1

> READ: io=1024.0MB, aggrb=8558KB/s, minb=8558KB/s, maxb=8558KB/s, mint=122519msec, maxt=122519msec

1GBの読み込みにしても実質8.5MB/s?…遅くないか???

続いて、ddで1GBの書き込み速度を計測してみる。

time dd if=/dev/zero of=/stock/fiodiskmark.0.0 bs=1M count=1000

NFS経由で三回書き込んでみた平均は62MB/秒!…速い!

ただ、これはArmbianからNFSサーバーへの読み書きなので、ストレージコンバーターとしての変換処理が入るとどうだろう?

・最終確認

では最後に

[REGZA…のつもりのPC(Win10)]
      ↑
(g_mass_storage/USB2.0)

[OPi2E]

   (NFS/GbE)

[R610 vps-home:/stock/]

を試してみる。

KVMな仮想環境にストレージサーバーを構築(ストレージ部分のディスクは2.5inchSAS、10kRPM、300GBでRAID-0)した。そこに先のテストと同様に、4GBのストレージ領域イメージファイルを作る。

dd if=/dev/zero of=/stock/test.img bs=1M count=4096

そして、このストレージ領域イメージファイルにfdiskでパーティションを作成して、typeをcにしてVFATにする。

fdisk /stock/test.img

VFATにしたら、ループバックデバイスとしてマウントしてフォーマットする。

losetup -o 1024k /dev/loop0 /stock/test.img
mkfs.vfat /dev/loop0
losetup -d /dev/loop0
sync
sync
sync

これでストレージ領域イメージファイルの準備ができたので、「g_mass_storage.ko」モジュールを使ってUSBストレージにする。

rmmod g_mass_storage
modprobe g_mass_storage file=/stock/test.img stall=0

有効にしたら、さっそくテスト。


NFS先を対象に50MBでテスト


NFS先を対象に1GBでテスト

結果としては、Readは20MB/s以上出るけど、Writeが16MB/s前後しか出ない。

@nogisawa 君の言うように、これがUSB2.0の限界なのか?

で、この仕組みを起動時に自動的に実行させるには、/etc/rc.localにでも

/sbin/modprobe g_mass_storage file=/stock/test.img stall=0 iProduct="OPi Storage Bridge"
/bin/echo 2 > /sys/bus/platform/devices/sunxi_usb_udc/otg_role

のようにすればよい。

・今後の改善検討

今回の構成ではバーチャルマシン(VM)の上のNFSという構成なのでオーバーヘッドが少しあるのかも?と思い、ホストに別のディスクイメージを用意して、それを直接NFSさせるのがよいのでは?と思って試してみた。

modprobe g_mass_storage file=/dev/vdb stall=0

だが、あまり速度の改善は見られなかった。

ではストレージコンバーターとして使用するマシンをOPi2Eではなく、もっと早いマシンにしたらどうだろう?

ということで、さっそくArmbianで他のマイコンボードをみたりOrange Piのサイトを見たりした。そしたら、「Orange Pi One Plus」(H6)と「Orange Pi PC2」(H5)がWi-Fiを積んでいなくて、かつOPi2Eよりも速そうだ。

ということでさっそくAliExpressでこれらをポチったので、これで作ってみた。


Orange Pi One Plus


Orange Pi PC2


OPi PC2のmicroSDを対象に100MBでテスト


OPi PC2をストレージコンバーターとしてNFS先を対象に100MBでテスト


OPi PC2をストレージコンバーターとしてNFS先を対象に1GBでテスト

…というように、あまり変わらなかった。というか、H3よりH5の方が遅いの!?
(それでも書き込み速度は112Mbpsは確保できそうだけど)

結局USB2.0である限り、もう少しストレージコンバーターに使うマイコンボードにコストをかけても、これくらいが限界値なのかもしれない。


左からOne Plus、PC2、Plus 2E

USB3.0のUSB-OTGを搭載しているマイコンボードが「格安」であれば、それで試しても面白いかもしれない。

ただし、REGZAのUSBが2.0である限り、意味がないけれど。 😛

で、

□ストレージコンバーター化したOrangePiをT〇SHIBAのRE〇ZAに繋いでみた

に続きます。 🙂


□ストレージコンバーター化したOrangePiをT〇SHIBAのRE〇ZAに繋いでみた

$
0
0

基本的に写真のみです。

判る人にはわかるかと思います。 🙂

 

 

 

わーい、動いた動いた\( ‘ω’)/

…で、外そうとしたら

工エエェェ(´д`)ェェエエ工

でもWin10でも、OPi(Armbian)側には外した場合の記録が何もないので、どうしようもないよなぁ…

まぁ「気にせず外せば?」といわれたので、それでいいか。(笑)

 

□Nginxのlogrotateスクリプトについて

$
0
0

Nginxに乗り換えたサイトで「証明書の有効期限が切れてますよー」と言われた。

「あれ?」と思って/etc/letsencrypt/live/をみても、シンボリックリンクもちゃんと最新のファイルになっている。

「え?」と思って、Let’s Encryptの自動更新スクリプトを走らせると、当然「skip」となる。

「はて?もしかして?」と思って、Nginxをsystemctl restart nginxすると、アクセスできた。

「あれれ?」と思って/etc/logrotate.d/nginxをみると、まぁ世間と同じくkill -USR1になってますけど…

「ひょっとして?」と思って/usr/lib/systemd/system/nginx.serviceみても、特別何をするとかでもなく…

「あー」と思って、他の同様のサーバーでkill -HUPでやってみたら、見れました。

kill -HUP以上をしないとサーバー証明書を取り込みなおしてくれないのねー、ちゃんちゃん。

 

□CentOS8でLet’ Encrypt

$
0
0

うっかり忘れていたけど、Let’s Encryptのツールにはcertbot-autoっていうのがあるんだった。

CentOS8にはまだcertbotがないけれど、certbot-autoを使うことで、CentOS8でもLet’s Encryptからサーバー証明書がさくっと取得できました。

cd /usr/bin/
wget https://dl.eff.org/certbot-auto
chmod 755 certbot-auto

cd
certbot-auto

来年からはCentOS8だな。 #サーバー構築ハンズオン

□MySQL8でInnoDBクラスターを試す

$
0
0

・まずは環境設定

CentOS8のインストールが終わった直後くらいの状態からの構築メモ。

dnf -y update
dnf -y install emacs-nox
dnf -y install epel-release
dnf -y install certbot # pythonも一緒に入ってくれるから手抜き

alternatives --config python

で、python3を指定する。

/usr/bin/env python

で動けばOK。

クラスタを構成するインスタンス(サーバー)のホスト名をhostsファイルに記述。

emacs /etc/hosts

192.168.79.210    cl000
192.168.79.211    cl001
192.168.79.212    cl002

さらに、コマンドプロンプトにもインスタンス名が出るようにする。

emacs /etc/hostname

cl000

さらに、SELinuxを無効にしておく。

emacs /etc/sysconfig/selinux

####SELINUX=enforcing
SELINUX=permissive

さらに、MySQLに対して外部からアクセスを許可させる。(3306番ポートの開放)

firewall-cmd --add-service=mysql --zone=public --permanent
firewall-cmd --reload

※本来であれば、これとは別にiptablesでクラスタを構成するインスタンスのみが3306番ポートにアクセスできるように制限すべき。

そしたらいったん再起動。

reboot

MySQL8のインストール

CentOS8が配っているディストリビューション版ではツールが足りないのと、そもそもセキュリティレベルが低すぎるので、きちんと(?)公式からコミュニティ版をインストールする。

dnf -y install https://dev.mysql.com/get/mysql80-community-release-el8-1.noarch.rpm

dnf --repo=mysql80-community search mysql-community

dnf --repo=mysql80-community info mysql-community-server

dnf -y install --repo=mysql80-community \
	mysql-community-server mysql-community-client mysql-community-common

dnf -y install mysql-shell mysql-router-community

※mysql-community-devel mysql-community-libsを入れようとすると、コンフリクトが発生するので注意。

でもって、MySQLサーバーの基本設定をする。

emacs /etc/my.cnf

    :
#default_authentication_plugin = mysql_native_password
default_authentication_plugin = mysql_native_password

slow_query_log = 1
slow_query_log_file = /var/lib/mysql/slow_query.log
long_query_time = 3

max_connections=200
innodb_file_per_table

loose-group_replication_ip_whitelist="192.168.79.0/24"
     :

※まだこの段階ではgroup_replication_ip_whitelistはエラーになるので接頭語「loose-」をつけてスルーさせる
 https://dev.mysql.com/doc/refman/8.0/en/group-replication-ip-address-whitelisting.html

そしたらMySQLを起動して、root用の一時パスワードを確認する。

systemctl enable mysqld
systemctl restart mysqld
systemctl status mysqld

grep --color=auto 'temporary password' /var/log/mysqld.log

rootの一時パスワードでいったんMySQLにログインして、パスワードを変更する。

mysql -u root -p

SET GLOBAL validate_password.length=0;
SET GLOBAL validate_password.mixed_case_count=0;
SET GLOBAL validate_password.number_count=0;
SET GLOBAL validate_password.special_char_count=0;
SET GLOBAL validate_password.policy=LOW;

ALTER USER 'root'@'localhost' IDENTIFIED BY 'kantan7pwd';

SHOW VARIABLES LIKE '%validate_password%';

EXIT;

※簡単なパスワードを設定できるようにvalidate_password.~を変更している

・続いてクラスタの設定

MySQL ShellでMySQLにログインしてクラスタ用のアカウントを設定する。

mysqlsh
\c root@localhost
dba.configureLocalInstance()

とすると

Configuring local MySQL instance listening at port 3306 for use in an InnoDB cluster…

This instance reports its own address as localhost.localdomain:3306
Clients and other cluster members will communicate with it through this address by default. If this is not correct, the report_host MySQL system variable should be changed.

ERROR: User 'root' can only connect from 'localhost'. New account(s) with proper source address specification to allow remote connection from all instances must be created to manage the cluster.

1) Create remotely usable account for 'root' with same grants and password
2) Create a new admin account for InnoDB cluster with minimal required grants
3) Ignore and continue
4) Cancel
Please select an option [1]:

と聞かれる。

rootをそのままネットワーク接続OKなアカウントとして設定するのはちょっとアレなので、クラスタ専用のアカウント(clroot)にするため、2を選択する。

そしてアカウントとそのパスワードの設定をする。

Please provide an account name (e.g: icroot@%) to have it created with the necessary
privileges or leave empty and press Enter to cancel.
Account Name: clroot
Password for new account: *
Confirm password: * 

パスワードの確認ができると、設定を変更するか、MySQLを再起動するかと聞かれるので、それぞれyとする。

NOTE: Some configuration options need to be fixed:
+--------------------------+---------------+----------------+--------------------------------------------------+
| Variable                 | Current Value | Required Value | Note                                             |
+--------------------------+---------------+----------------+--------------------------------------------------+
| binlog_checksum          | CRC32         | NONE           | Update the server variable                       |
| enforce_gtid_consistency | OFF           | ON             | Update read-only variable and restart the server |
| gtid_mode                | OFF           | ON             | Update read-only variable and restart the server |
| server_id                | 1             |                | Update read-only variable and restart the server |
+--------------------------+---------------+----------------+--------------------------------------------------+

Some variables need to be changed, but cannot be done dynamically on the server.
Do you want to perform the required configuration changes? [y/n]: y
Do you want to restart the instance after configuring it? [y/n]: y

とすると、

Cluster admin user 'clroot'@'%' created.
Configuring instance…
The instance 'cl000:3306' was configured to be used in an InnoDB cluster.
Restarting MySQL…
NOTE: MySQL server at cl000:3306 was restarted.

となるので、設定状況を確認してみる。

dba.checkInstanceConfiguration('clroot@cl000')
Please provide the password for 'clroot@cl000': *
Save password for 'clroot@cl000'? [Y]es/[N]o/Ne[v]er (default No):
Validating local MySQL instance listening at port 3306 for use in an InnoDB cluster…

This instance reports its own address as cl000:3306
Clients and other cluster members will communicate with it through this address by default. If this is not correct, the report_host MySQL system variable should be changed.

Checking whether existing tables comply with Group Replication requirements…
No incompatible tables detected

Checking instance configuration…
Instance configuration is compatible with InnoDB cluster

The instance 'cl000:3306' is valid to be used in an InnoDB cluster.

{
     "status": "ok"
}

となればOK。

グループレプリケーション用の33061番ポートを「それぞれのインスタンス」で開ける。

emacs /etc/firewalld/services/mysql-cluster.xml

<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>MySQL</short>
  <description>MySQL Database Server Group Replication</description>
  <port protocol="tcp" port="33061"/>
</service>


少し待ってfirewalldがこのxmlファイルを認識したら、

firewall-cmd --add-service=mysql-cluster --zone=public --permanent
firewall-cmd --list-services --zone=public  --permanent
firewall-cmd --reload

とすれば、インスタンス間でクラスタ用の通信が行えるようになる。

これを他のインスタンス(cl001, cl002)でも同様に行う。

・実際のクラスタの作成

ここまでの準備ができたら、あとは実際にクラスタを作成する。

まずはプライマリインスタンス(cl000)にて、

mysqlsh
\c clroot@cl000
dba.createCluster('Cluster000')

とすると、

A new InnoDB cluster will be created on instance 'cl000:3306'.

Disabling super_read_only mode on instance 'cl000:3306'.
Validating instance configuration at cl000:3306…

This instance reports its own address as cl000:3306

Instance configuration is suitable.
NOTE: Group Replication will communicate with other members using 'cl000:33061'. Use the localAddress option to override.

Creating InnoDB cluster 'Cluster000' on 'cl000:3306'…

Adding Seed Instance…
Cluster successfully created. Use Cluster.addInstance() to add MySQL instances.
At least 3 instances are needed for the cluster to be able to withstand up to
one server failure.

<Cluster:Cluster000>

としてプライマリインスタンスができる。

そしたら、インスタンス(cl001とcl002)を追加する。

cluster = dba.getCluster()

とすることで、clusterに「Cluster000」が関連付けされるので

cluster.status()

とすると、

{
    "clusterName": "Cluster000",
    "defaultReplicaSet": {
        "name": "default",
        "primary": "cl000:3306",
        "ssl": "REQUIRED",
        "status": "OK_NO_TOLERANCE",
        "statusText": "Cluster is NOT tolerant to any failures.",
        "topology": {
            "cl000:3306": {
                "address": "cl000:3306",
                "mode": "R/W",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.19"
            }
        },
        "topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "cl000:3306"
} 

のようにして、クラスタに対しての操作ができるようになるので、さっそくインスタンスを追加してみる。

cluster.addInstance('clroot@cl001')

とすると、どのようなリカバリ(複製)モードにするか聞かれる。

NOTE: The target instance 'cl001:3306' has not been pre-provisioned (GTID set is empty). The Shell is unable to decide whether incremental state recovery can correctly provision it.
The safest and most convenient way to provision a new instance is through automatic clone provisioning, which will completely overwrite the state of 'cl001:3306' with a physical snapshot from an existing cluster member. To use this method by default, set the 'recoveryMethod' option to 'clone'.

The incremental state recovery may be safely used if you are sure all updates ever executed in the cluster were done with GTIDs enabled, there are no purged transactions and the new instance contains the same GTID set as the cluster or a subset of it. To use this method by default, set the 'recoveryMethod' option to 'incremental'.

Please select a recovery method [C]lone/[I]ncremental recovery/[A]bort (default Clone): 

今回は初めてのクラスタ構築なので、C(複製)でもI(増分リカバリ)でもどちらでもOK。

https://dev.mysql.com/doc/refman/8.0/en/mysql-innodb-cluster-working-with-clone.html

とすると、

NOTE: Group Replication will communicate with other members using 'cl001:33061'. Use the localAddress option to override.

Validating instance configuration at cl001:3306…

This instance reports its own address as cl001:3306

Instance configuration is suitable.
A new instance will be added to the InnoDB cluster. Depending on the amount of 
data on the cluster this might take from a few seconds to several hours.

Adding instance to the cluster…

Monitoring recovery process of the new cluster member. Press ^C to stop monitoring and let it continue in background.
Clone based state recovery is now in progress.

NOTE: A server restart is expected to happen as part of the clone process. If the
server does not support the RESTART command or does not come back after a
while, you may need to manually start it back.

* Waiting for clone to finish…
NOTE: cl001:3306 is being cloned from cl000:3306
** Stage DROP DATA: Completed
** Clone Transfer
   FILE COPY  ############################################################  100%  Completed
   PAGE COPY  ############################################################  100%  Completed
   REDO COPY  ############################################################  100%  Completed
** Stage RECOVERY: |
NOTE: cl001:3306 is shutting down…

* Waiting for server restart… ready
* cl001:3306 has restarted, waiting for clone to finish…
* Clone process has finished: 61.72 MB transferred in about 1 second (~1.00 B/s)   

State recovery already finished for 'cl001:3306'

The instance 'cl001' was successfully added to the cluster. 

として、インスタンスの追加ができたら、もう一つ(cl002)も追加。

cluster.addInstance('clroot@cl002')

こちらも

    :
The instance 'cl002' was successfully added to the cluster. 

となれば、追加完了。

cluster.status()
{
    "clusterName": "Cluster000",
    "defaultReplicaSet": {
        "name": "default",
        "primary": "cl000:3306",
        "ssl": "REQUIRED",
        "status": "OK",
        "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
        "topology": {
            "cl000:3306": {
                "address": "cl000:3306",
                "mode": "R/W",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.19"
            },
            "cl001:3306": {
                "address": "cl001:3306",
                "mode": "R/O",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.19"
            },
            "cl002:3306": {
                "address": "cl002:3306",
                "mode": "R/O",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.19"
            }
        },
        "topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "cl000:3306"
} 

これでcl000(プライマリ)、cl001(リードオンリー)、cl002(リードオンリー)のクラスタ構築ができた。

※/var/lib/mysql/mysqld-auto.cnfというファイルができる。

・MySQL Routerの設定

クラスタを構成したら、プライマリインスタンスに対して直接接続してあれこれしてもいいが、MySQL Routerというバランサーツールがあるので、これを素直に使うほうがよい。

https://dev.mysql.com/doc/refman/8.0/en/mysql-innodb-cluster-using-router.html

公式ドキュメントには、MySQL Routerはアプリケーションと同じホストでの動作を推奨しているが、とりあえず今回はプライマリインスタンス上でMySQL Routerも動かしてしまう。

まずはcl000(プライマリ)を指定して、初期設定をする。

mysqlrouter --bootstrap clroot@cl000 --user=mysqlrouter

としてパスワードを入力(mysqlshellのような*のエコーバックは無い)すると、

Please enter MySQL password for clroot:
# Bootstrapping system MySQL Router instance…

- Creating account(s) (only those that are needed, if any)
- Verifying account (using it to run SQL queries that would be run by Router)
- Storing account in keyring
- Adjusting permissions of generated files
-  Creating configuration /etc/mysqlrouter/mysqlrouter.conf   

Existing configuration backed up to '/etc/mysqlrouter/mysqlrouter.conf.bak'

# MySQL Router configured for the InnoDB Cluster 'Cluster000'

After this MySQL Router has been started with the generated configuration

      $ /etc/init.d/mysqlrouter restart
   or
      $ systemctl start mysqlrouter
   or
      $ mysqlrouter -c /etc/mysqlrouter/mysqlrouter.conf

the cluster 'Cluster000' can be reached by connecting to:

## MySQL Classic protocol

- Read/Write Connections: localhost:6446
- Read/Only Connections:  localhost:6447   

## MySQL X protocol

- Read/Write Connections: localhost:64460
- Read/Only Connections:  localhost:64470    

というメッセージが出て、設定が完了する。

※/etc/mysqlrouter/mysqlrouter.confに設定が出力される。

MySQL Routerをサービスとして常に動かす場合には、メッセージにあるように

systemctl ebanle mysqlrouter
systemctl start mysqlrouter
systemctl status mysqlrouter

とすればよい。

・シングルプライマリモードのテスト

プライマリインスタンス(cl000)で

mysql -u root -p

としてMySQLにログインをしてテスト用のデータベースとユーザーを作る。


use mysql;

DROP DATABASE IF EXISTS `test001_db`;
DROP USER IF EXISTS 'test001'@'localhost';
DROP USER IF EXISTS 'test001'@'%';
FLUSH PRIVILEGES;

CREATE DATABASE `test001_db`;

CREATE USER 'test001'@'localhost' IDENTIFIED BY 'test001pwd';
CREATE USER 'test001'@'%' IDENTIFIED BY 'test001pwd';

SELECT user, host, plugin, authentication_string FROM user;

GRANT ALL ON `test001_db`.* TO 'test001'@'localhost';
GRANT ALL ON `test001_db`.* TO 'test001'@'%';
FLUSH PRIVILEGES;

EXIT;


すると、自動的にリードオンリーインスタンス(cl001, cl002)にもデータベースができるので、プライマリインスタンス(cl000)で、テスト用のデータベースを操作してみる。

普通にmysql(クライアント)コマンドでプライマリインスタンスに接続してもいいが、せっかくMySQL Routerを動かしたので、こちらに接続してみる。

mysql --host=cl000 --port=6446 --user=test001 -p
use test001_db;

DROP TABLE IF EXISTS `test001`;

CREATE TABLE test001
(
  column01      int,
  column02      text,
  column03      text,
  PRIMARY KEY(column01)
);

INSERT INTO test001 VALUES (1, 'bbb', 'ccc');

※テーブルにプライマリキーがないとダメ

※リードオンリーポートで上記SQLを試してみると、ちゃんとエラーになる。
 mysql –host=cl000 –port=6447 –user=test001 -p

・やっとMySQL8のクラスタ構築ができたので…

あとは公式ドキュメントを読みながら、インスタンスを止めたりして高可用性を試したり、マルチプライマリモードも試してみたい。

□Postfix+Amavisd+ClamAVをCentOS8で動かすときのTips!?

$
0
0

CentOS8を再起動したときにClamAVがきちんと起動しきれないためにウィルススキャンの動作がおかしくなることがあった。

たぶんに起動順番ではないかと思うので、以下のようにしてみる。

・Amavisd用のClamAVは、Amavisdの起動時についでに起動される。
・なので、Amavisdの起動を待ってからPostfixを起動するようにしてみた。

systemctl disable amavisd.service
systemctl disable clamd@.service

mkdir /usr/lib/systemd/system/postfix.service.d/

cat > /usr/lib/systemd/system/postfix.service.d/amavisd.conf

--------------------------------
[Unit]
Wants=amavisd.service
After=amavisd.service

[Service]
# Wait for /var/run/clamd.amavisd/clamd.sock etc
ExecStartPre=/usr/bin/sleep 15
--------------------------------

systemctl daemon-reload

systemctl restart postfix.service

あとはサーバーそのものを再起動してみて、amavisdもclamavも起動してればOK。

※お行儀がいいひとは、「/usr/lib/systemd/system/postfix.service.d/~」に作るのではなくて、「/etc/systemd/system/postfix.service.d/~」に作りましょう。 🙂
※Amavisdのソケット通信用の.sockファイルの生成に時間がかかるので、Postfixの起動を15秒待つようにした

Viewing all 69 articles
Browse latest View live