それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

PC(マザーボード)を交換したらネットワーク認識しなくなった件/enp1s0は怖いよ 

enp1s0 とか enp2s1 とかネットワークデバイス接続順で名前が決まるからSSDまるごと別のPCに移動させたときに、ネットワークデバイスが全滅する。eth0 に戻したい。

ubuntuの載ったサーバー本体を交換しました。

昨日、HDDを古いサーバーから、新しいサーバーに持ち込んで、起動しました。

無事に起動するのですが、ネットワークが完全に死んでいました。Ubuntuでネットワークがつながらないという。事故が起きました。

原因は enp1s0/enp2s0f0とnetplan

いままで使っていた、サーバー機では、ネットワークカードは enp2s0f0 という名前でした。

しかし、SDD載せ替えた新しいサーバーでは、NICenp1s0という名前でした。

そして、ubuntu では netplan を使っています。netplan に enp2s0f0を書いていました。

/etc/netplan/50-cloud-init.yaml

# vim: tabstop=2 sw=2 nowrap expandtab  :
 network:
   version: 2
   renderer: networkd
   ethernets:
     enp2s0f0:
       dhcp4: false
       dhcp6: false
   vlans:
     enp2s0f0.10:
       addresses: []
       id: 10
       link: enp1s0
(以下略

nic の名前の変更が、ネットワーク設定を亡き者した。

enp2s0f0enp1s0 という名前の変更が、ネットワークにつながらない原因でした。これは怖いことです。

ネットワーク設定が eth0 と書かれいたら起こり得なかったことだと思います。現代では一貫性のある名前をつけるために、以前のネットワーク設定がロードされずネットワークにつながらないというトラブルが起きます。Ubuntuを使っていると、これから先だれでも一度は絶対に遭遇する。罠だと思います。

eth0 /eth1 なら起きなかった。

ubuntu 16くらいの従来どおり、eth0 という名前のネットワークデバイス名であれば、このようなことは起こりえません。最初に見つかったネットワークデバイスはいつでもeth0 なので。

enpXXXX のような名前は、PCIバイスの接続箇所の順番を示しているのですが。これがあるとネットワーク設定を使い回すことができず。思わぬトラブルをヒキコ推しました。

enpXXX を使わない。としたい。

安定して稼働させるために、enpXXXを使わないという選択肢もいいと思います。

Redhatは無効にしないでくださいと書いていましたが、それって結局不便だよね。って思った次第です。

たぶん他に困ったことになった人も多いと思う。いつでもDHCPでアドレスを取ってくるとは限らないので、怖い問題だと思う。

netplan でやると恒常的な変更にならない。

grubカーネルオプションを渡したら、永続化する

永続化する方法はこちら

参考資料

USBメモリ(フラッシュドライブ)がお亡くなりになったので

USB メモリが寿命を迎えました。

USBフラッシュドライブで、Ubuntuを入れたり、MacOSを外部ブートで入れたり、Windowsのインストールディスクになったり、OPNSenseのインストールディスクなったり、ずっと活躍してくれた、USBフラッシュドライブが亡くなりました。

USBドライブが寿命を迎えるとき

USBドライブは寿命を迎えると、「読み込み専用」になるようです。ファームウェアによりデータ保護のために、読み込み専用になるんですね。

dmseg です。

一見すると、正常に動作してそうですが。

[725469.458704] usb-storage 1-1.3:1.0: USB Mass Storage device detected
[725469.463140] scsi host1: usb-storage 1-1.3:1.0
[725470.480671] scsi 1:0:0:0: Direct-Access     SanDisk  Ultra Fit        1.00 PQ: 0 ANSI: 6
[725470.482221] sd 1:0:0:0: Attached scsi generic sg0 type 0
[725470.482706] sd 1:0:0:0: [sdb] 30031250 512-byte logical blocks: (15.4 GB/14.3 GiB)
[725470.484410] sd 1:0:0:0: [sdb] Write Protect is on
[725470.484420] sd 1:0:0:0: [sdb] Mode Sense: 43 00 80 00
[725470.485081] sd 1:0:0:0: [sdb] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA

hdparm を見ると。

READ ONLY になっています。

takuya@raspi-ubuntu:~$ sudo hdparm  /dev/sdb

/dev/sdb:
SG_IO: bad/missing sense data, sb[]:  f0 00 05 00 00 00 00 14 00 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 multcount     =  0 (off)
 readonly      =  1 (on)
 readahead     = 256 (on)
 geometry      = 14663/64/32, sectors = 30031250, start = 0

これが、データ保護のためにREAD ONLYになるってやつですね。

mount しても

takuya@raspi-ubuntu:~$ sudo mount -o rw /dev/sdb1 /mnt
mount: /mnt: WARNING: device write-protected, mounted read-only.

リードオンリーです。

強引に読み込み専用フラグを無視しても

hdparm で読み込み専用のフラグを外しても。

takuya@raspi-ubuntu:~$ sudo hdparm -r0 /dev/sdb

/dev/sdb:
 setting readonly to 0 (off)
 readonly      =  0 (off)
takuya@raspi-ubuntu:~$ sudo mount -o rw /dev/sdb1 /mnt
mount: /mnt: WARNING: device write-protected, mounted read-only.

もう、二度と書き込みができるようにはならないようです。お疲れ様でした。

いろいろ、コマンドを試したけどエラーメッセージは微妙に違いますね。

mkfs

takuya@raspi-ubuntu:~$ sudo mkfs.ext4 /dev/sdb
mke2fs 1.45.5 (07-Jan-2020)
Found a dos partition table in /dev/sdb
Proceed anyway? (y,N) y
/dev/sdb: Read-only file system while setting up superblock

wipefs

takuya@raspi-ubuntu:~$ sudo wipefs -a /dev/sdb
wipefs: error: /dev/sdb: probing initialization failed: Read-only file system

fdisk

takuya@raspi-ubuntu:~$ sudo fdisk /dev/sdb

Welcome to fdisk (util-linux 2.34).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

fdisk: cannot open /dev/sdb: Read-only file system

fsck

takuya@raspi-ubuntu:~$ sudo fsck.vfat -f -v /dev/sdb1
fsck.fat 4.1 (2017-01-24)
open: Read-only file system

数年間お疲れ様でした。

これから先に、USBフラッシュドライブが即死したときに、こんなエラーがでたら寿命だよって気づくために、記録を残しておきます。

保証申請

保証申請もありますが、型番や保証書、買ったときのレシートなどが必要です。

どんなときでも、レシートは残しておく必要がありますね。

また、海外リテール品は国内サポート窓口では一切のサポートを受けられません。

保証申請を考えるのであれば、国内向け正規品を買っておく必要があります。

高額・大容量は買わないこと。

USBフラッシュドライブは、大容量になればなるほど、故障時の精神的・金銭的ダメージが大きくなる。紛失のダメージも大きい。 そんなに良いものを求める理由はありません。良いものがほしいときは、現代では、nvme/STAT3の2230/2280のSSDをUSBドライブ化する事を考えたほうが良いですよ。SDカードはすぐ壊れるので、おすすめしませんが、ドライブレコーダー用の長寿命SDカードなら、大容量で高額なUSBフラッシュドライブよりもマシな選択肢です。

1000円までで安いものを買って置くのが良いと思います。

8GB・16GB・32GBだと、32GBのほうが書き込み速度が出ます。そういうのは考慮していいと思う。 USB2.0USB3.0であれば、読み書き速度がボトルネックになるので、ほとんど差がありません。が、USB3.0/3.1のほうが比較的マシなUSBメモリの内部構造になってると思われます。

暗号化機能?そんなものはソフトウェアでやるべきです。

nginx → apache のhttp2 プロキシ設定

nginx →Apachehttps のプロキシ設定をしていて、動かないので、ちょっと頭を抱えた。

次のようにプロ棋士していたが

ブラウザ--<ssl/http>--nginx(ssl/h2)--<http>-- apache 

ある日の更新で次のように変わった。

ブラウザ--<ssl/h2>--nginx(ssl/h2)--<http>--apache 

すると、curl などブラウザで閲覧するとエラーになった。

ところが、Windowsではエラーにならずに、そのまま見えていたので気づかなかった。 Windowsで見れて、iOSから閲覧できないというミスが発生した。

curl で見ると、次のようにエラーになる

http2 error: Invalid HTTP header field was received:

iOS を見ると、次のようにエラーになる。

エラー

応答を解析できません。

f:id:takuya_1st:20211106180201p:plain

通信状況がおかしくなる。

次のように通信しているが、nginxがうまくさばいてくれなかったみたい

ブラウザ--<ssl/h2>--nginx(ssl/h2)--<http>--apache 

実際には、このように通信しようとしておかしくなったみたい

# リクエスト時
ブラウザ--<ssl/h2>--nginx(ssl/h2)--<http>--apache 
# レスポンス時
apache--<http/1.1>--nginx(ht2?)---<https/1.1>--ブラウザ

エラーが出なかったときは、キャッシュ見てたり状況次第だったようだ。

apacheにh2を喋らせる。

Apache 側でこれを入れて解決。

Protocols http/1.1 h2c h2 

設定を書き換えた。

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
<VirtualHost *:443 > # 80ではなく、h2のために443へ
  LogLevel  warn
  ServerName  example.com
  Protocols http/1.1 h2c h2 # 追加
  SSLEngine on
  SSLCertificateFile 自己署名など適当な.cert.pem # 追加 
  SSLCertificateKeyFile 適当な.private.key.pem # 追加

  UseCanonicalName Off
  VirtualDocumentRoot /var/www//html

  <Directory /var/www/html >
    Options All
    AllowOverride All
    AddHandler cgi-script .cgi
  </Directory>
  <Files ~ "^\.ht">
    Order allow,deny
    Deny from all
    Satisfy All
  </Files>
</VirtualHost>

その他の考えられる解決策

nginx.conf と nginxのサイト設定で、ちゃんとプロキシ処理とプロトコル設定を記述すればいいと思うのだが。

nginx 側で proxy_set_header X-Forwarded-Proto https;proxy_set_header X-Forwarded-Proto http; を加えてやれば、うまく動作するはずである。

nginx で よくある設定 proxy_set_header X-Forwarded-Proto $scheme; でh2のまま送信されちゃう apache2 側で Protocols http/1.1にして h2 を完全に無効にしてあげてもいいかもしれない。

ちょっとnginx の設定を触りづらい環境にあったのでnginxは無視した対応を考えた。

bashで文字列の中身の変数名の値を取り出す(可変変数・間接参照)

bash で配列に入れた文字列を変数として解釈する

変数の文字列を、変数として解釈する。

echo $name=${!name}

たとえば変数調べるときに変数名を列挙して中身を全部見るとか。

#!/usr/bin/env bash 
for i in ip mask subnet subnet interface router ; do
  echo $i=${!i}
done

可変変数とかvariable variable とか一般呼称はあるのですが、あまり普及してないですね。

bashのマニュアルを見ると、indirect access なので間接参照とかの邦訳になります。

文字列を変数名として解釈するとか、文字列から変数を取り出すとか。変数名を使って別の変数を取り出すとか、人によって表現にゆらぎが出るので困りますね。英語でも variable variables のように表現する人も多く、表現にゆらぎが出るので困りますね。

関連資料

takuya-1st.hatenablog.jp

参考資料

OpenWrt で softether のVPN接続する、udhcpdによるIP取得とルーティングする

openWrt で softetherVPNをルーティングする

openwrt に vpn 拠点間接続をやらせてみる

リモート側のネットワークの設定やマスカレードなどは済んでいる状態。OpenWRTからリモートへ接続する

Host-->openwrt--<SoftEtherVPN>--VPN Server--(office network)--10.193.3.40

細かいことは抜いておいて、相手先のネットワークのサーバーにアクセスできればいい。

openwrt に softether のクライアントを入れる

opkg install softethervpn-client

vpnclientvpncmd が導入される。

インストールするとClientが起動している

localhostSoftEther のクライアントが起動している。起動を確認しておく。

root@OpenWrt:~# ps auxf | grep softethervpn
root      2116  0.0  0.0   6644  1600 ?        S<s  03:48   0:00 /usr/libexec/softethervpn/vpnclient execsvc
root      2119  0.9  0.1  23000 16528 ?        S<l  03:48   0:02  \_ /usr/libexec/softethervpn/vpnclient execsvc

SoftEtherの設定 vpncmd

このあたりはmacOS/Ubuntu で接続するときと同じ

vpncmd /CLIENT localhost /CMD NicCreate
vpncmd /CLIENT localhost /CMD AccountList
vpncmd /CLIENT localhost /CMD AccountCreate
vpncmd /CLIENT localhost /CMD AccountPasswordSet
vpncmd /CLIENT localhost /CMD AccountConnect ocn
vpncmd /CLIENT localhost /CMD AccountList
コマンド 設定値
NicCreate soeth0
AccountCreate /name:ocn /nic:soeth0 /hub=Vpn /remote=vpn.my-office.jp:443
AccountPasswordSet パスワード

上記のとおりにコマンドをいれてもいいが、毎回毎回訊かれるのが面倒。

コマンドの引数を使ってコピペ可能にする。

## 共通化
alias vpncmd='vpncmd /CLIENT localhost /CMD ' # コマンド省略
conn=ocn-tak # 接続名
## 接続作成
vpncmd NicCreate soeth0
vpncmd AccountCreate $conn /SERVER:vpn.ocn.ac.tld:443 /USERNAME:takuya1234 /HUB:USER_HUB /NICNAME:vpn_soeth0
vpncmd /CLIENT localhost /CMD AccountPasswordSet $conn  /PASSWORD:mypassword /TYPE:radius

## 接続と確認
vpncmd /CLIENT localhost /CMD AccountConnect  $conn
vpncmd /CLIENT localhost /CMD AccountList 
vpncmd /CLIENT localhost /CMD AccountStatusGet $conn
## 切断と確認
vpncmd /CLIENT localhost /CMD AccountDisConnect  $conn
vpncmd /CLIENT localhost /CMD AccountList 
vpncmd /CLIENT localhost /CMD AccountStatusGet $conn

接続すると、Nicの名前に vpn_プレフィックスされたインターフェイスが現れる。

今回は、Nic の名前を soeth0 としたので、 vpn_soeth0 が出現する。

dhcpでアドレスを取得

openwrt の場合、udhcp を使えばいいので、それ用のスクリプトを用意する。

アドレス取得時に、最低限のルーティングを行うのだが

最初は動作確認のために、ルーティングは書かずにアドレスだけもらっておく。

ルーティングは動作確認後に後で追記する。

etc/config/custom/softether/dhcp.sh(ルーティングなし)

#!/usr/bin/env bash

setup_interface() {
  echo "udhcpc: ifconfig $interface $ip netmask ${subnet:-255.255.255.0} broadcast ${broadcast:-+}"
  ifconfig $interface $ip netmask ${subnet:-255.255.255.0} broadcast ${broadcast:-+}
    # info
  echo router=${router}
  
}
case "$1" in
  deconfig)
    ifconfig "$interface" 0.0.0.0
    ;;
  renew)
    setup_interface update
    ;;
  bound)
    setup_interface ifup
    ;;
esac

udhcp でアドレス取得

これで、IPアドレスが取得される。

udhcpc -i vpn_soeth0 -s /etc/config/custom/softether/dhcp.sh

ルーティング

仮想Hub経由してルータに接続する。

ping 10.35.225.254

ルータに接続できたら、GWとして、ルーティングを入れてやる。

ip route add 10.193.3.0/24 via 10.35.225.254 dev vpn_soeth0

ルーティングテーブル追加の確認。pingで接続を確認する。

ping 10.193.3.40

これで、OpenWRTから、リモート側のPCまで到達できた。

VPN接続を共有する(マスカレード)

OpenWRTにルータらしく、NATとマスカレードをして、ローカル側にVPN接続を共有させる。

要は、マスカレードとフォワーディングを入れてやる。

VPN_IF=vpn_soeth0
iptables -I FORWARD -o $VPN_IF -j ACCEPT
iptables -t nat -A POSTROUTING -o $VPN_IF -j MASQUERADE

共有を確認する

192.168.1.100 から 10.193.3.40へ接続を確認する

takuya@work $ ssh 192.168.1.100 
takuya@192.168.1.100 $ ping 10.193.3.40

パケットが応答されたので、接続できた。

設定を永続化する。

最後に、udhcp の起動スクリプトに、これらのルーティングを書き加える。

etc/config/custom/softether/dhcp.sh(ルーティング追加)

#!/usr/bin/env bash

setup_interface() {
  echo "udhcpc: ifconfig $interface $ip netmask ${subnet:-255.255.255.0} broadcast ${broadcast:-+}"
  ifconfig $interface $ip netmask ${subnet:-255.255.255.0} broadcast ${broadcast:-+}
    ### 追加
  # routing
  ip route add 10.193.3.0/24 via ${router} dev ${interface}
  # masquerade
  iptables -I FORWARD -o ${interface} -j ACCEPT
  iptables -t nat -A POSTROUTING -o ${interface} -j MASQUERADE
}

case "$1" in
  deconfig)
    ifconfig "$interface" 0.0.0.0
    ;;
  renew)
    setup_interface update
    ;;
  bound)
    setup_interface ifup
    ;;
esac

動作チェックする。

## iptables を初期化して
service firewall restart
## ip を解放してルーティング・テーブルをリセット
ifconfig vpn_soeth0 0.0.0.0
## softether を切断
vpncmd /CLIENT localhost /CMD AccountDisConnect ocn

## softethre を接続
vpncmd /CLIENT localhost /CMD AccountConnect ocn
## dhcp 取得とルーティング設定
udhcpc -i vpn_soeth0 -s /etc/config/custom/softether/dhcp.sh

接続を切断して、再接続し、dhcp を再取得、udhcが指定スクリプトを動かす。

udhcp が取得後に、指定スクリプトを実行して、ipアドレス設定とルーティングを設定コマンドを流してくれる。

この一連の流れをコマンド化

/etc/config/custom/softether/start-my-softether-connection.sh

vpncmd /CLIENT localhost /CMD AccountDisConnect ocn
vpncmd /CLIENT localhost /CMD AccountConnect ocn
udhcpc -i vpn_soeth0 -s /etc/config/custom/softether/dhcp.sh

udhcpc の接続をrenew/releaseする

udhcpc は常駐させるモードと常駐させないモードが有る。

udhcpc -S -C -i $VPN_IF -s $UDHCP_SCRIPT        # プロセスが常駐する
udhcpc -q -S -C -i $VPN_IF -s $UDHCP_SCRIPT    # 実行したら終わり。プロセスは常駐しない。

プロセスを常駐している場合、シグナルで、renew/releaseが可能になる。

## dhcp を renew する
 pkill -USR1 -f "udhcpc -S -C -i $VPN_IF -s $UDHCP_SCRIPT"
## dhcp を release する
 pkill -USR2 -f "udhcpc -S -C -i $VPN_IF -s $UDHCP_SCRIPT"

それぞれ、終了後にスクリプト実行して、ルーティングなどの処理を追加することができる。

割当解放(リリース)した場合は /bin/sh $UDHCP_SCRIPT deconfig が呼ばれ、割当更新(renew)した場合は、/bin/sh $UDHCP_SCRIPT renew がそれぞれの引数(deconfig , renew, bound )をつけて実行される。

この引数を使ってdhcp割当・解放・更新のスクリプトを書くことができる。

スクリプト

# router, interface ip の変数はudhcpcから渡される
function cleanup_interface(){
  ## ルーティング解放・IP割当解除などの処理
 nft del table my_vpn
  ip route del ${DEST_NET} via ${router} dev ${interface} 
  ifconfig $interface 0.0.0.0
}
function setup_interface (){
  ## IP割当処理、ルーティング作成などの処理
  ifconfig $interface $ip netmask ${subnet:-255.255.255.0} broadcast ${broadcast:-+}
  ip route add ${DEST_NET} via ${router} dev ${interface} 
  nft add table my_vpn
}

case "$1" in

  deconfig)
    cleanup_interface
    ;;
  renew)
    setup_interface update
    ;;
  bound)
    setup_interface ifup
    ;;

esac

常駐している場合にシグナルを受け取って片付けのdeconf 処理を書くことができる。

pppoe 接続時にSoftEtherVPN接続を起動する

ppooe 接続時にスクリプトを動かすには、hotplug.d を使えばいいので、hotplug で実行するスクリプトを作る。

PPPoEが起動したら、間髪入れず、SoftEther を接続しに行くようにする。

/etc/hotplug.d/iface/99-softether

#!/usr/bin/env bash
## PPPoE接続後に、 スクリプトを実行する
## iface の変化後に、TARGET_INTERFACEで検出して任意のフックが可能
## main
function main(){
  TARGET_INTERFACE=pppoe-XXX
  TARGET_DEVICE=eth1
  ###
  [ "$ACTION" = "ifup" -a "$INTERFACE" = "$TARGET_INTERFACE"  ] && {
    # log sample
    logger "iface $TARGET_INTERFACE / $TARGET_DEVICE up detected, do hotplug actions."
    sleep 10;
        /etc/config/custom/softether/start-my-softether-connection.sh   
    }
}
main

最後の最後に、再接続チェック

ネットワークを再起動して、pppoe接続後にsoftether がちゃんと接続されて、ルーティングとマスカレードされることを確認する。

root#openWrt $ service network restart

注意点

実験用openWrt ルータはx86/ext4 で動作しているので、パッケージを容量気にせずに入れている。

bash / iproute2 / iptables-full など割と大きめのパッケージを入れて、そのへんのubuntu とおなじような動作しているので、容量がシビアなwrt だとこの方法だとうまくイカないかもしれない。

2023-08-29 追記

接続コマンドと作成コマンドをダイアログではなくコマンド引数で与えるようにメモを更新。

2023-08-30 追記

udhcpc の使い方が足りなかったので調査して追記。

参考資料

mac で softetherVPN への接続(クライアント)

macsoftether への接続

できなくはないけど、設定がめんどくさい。

いくつか手順が必要。

公式マニュアルは、L2TP over IPSec なのですが、IPSec 上に L2TPを通して、その上にSSHを通してってもう考えたくないので、カプセル化は少ないほうが管理上も速度面でも嬉しいので、直接つなぎます。*1

tap の準備

brew install tuntap
sudo reboot 

私は上記コマンドだけでインストール完了し、Kextを有効にするために再起動をした。

ただ、私の環境はcsrutils がオフになっているので、一般的に動くかどうかはわからない。

kext を使うので、macOSのCSPが使える必要があるかもしれない。 SIP ( sytem itegrity protection )をdisableで使う。

csrutil status
csrutil disable

sip spctl 関連資料

softether の準備

softethermac版はコマンドクライアントから持ってきます。

ダウンロード

ダウンロードサイトから、macOS版をダウンロードする。

https://www.softether-download.com/en.aspx?product=softether

 curl -LJO https://github.com/SoftEtherVPN/SoftEtherVPN_Stable/releases/download/v4.38-9760-rtm/softether-vpnclient-v4.38-9760-rtm-2021.08.17-macos-x64-64bit.tar.gz

f:id:takuya_1st:20211103200748p:plain

ビルド

tar zxvf softether-vpnclient*
cd vpnclient
make 

softether client の起動

クライアントは常駐するソフトである。そういう設計らしい。まぁもともとWindowsのタスクトレイに居座るタイプだし、MacOSのメニューバーに居座ることをしてないので、自分で起動するってことかな。

まず起動します。

cd vpnclient
sudo ./vpnclient start

使用終わったら stop

sudo ./vpnclient stop

stop するの忘れがち。

softether の接続設定を作る

vpnclient に接続します。

  • 2 client の管理
  • localhost 指定で自ホストのClientと対話
  • VPNClientでコマンドで操作
takuya@vpnclient$ sudo ./vpncmd
vpncmd コマンド - SoftEther VPN コマンドライン管理ユーティリティ
SoftEther VPN コマンドライン管理ユーティリティ (vpncmd コマンド)
Version 4.38 Build 9760   (Japanese)
Compiled 2021/08/17 22:32:49 by buildsan at crosswin
Copyright (c) SoftEther VPN Project. All Rights Reserved.

vpncmd プログラムを使って以下のことができます。

1. VPN Server または VPN Bridge の管理
2. VPN Client の管理
3. VPN Tools コマンドの使用 (証明書作成や通信速度測定)

1 - 3 を選択: 2

接続先の VPN Client が動作しているコンピュータの IP アドレスまたはホスト名を指定してください。
何も入力せずに Enter を押すと、localhost (このコンピュータ) に接続します。
接続先のホスト名または IP アドレス: localhost

VPN Client "localhost" に接続しました。

VPN Client>

仮想NICを作成する

tap に接続されるSoftetherNICを作成する。

VPN Client>NicCreate
NicCreate コマンド - 新規仮想 LAN カードの作成
仮想 LAN カードの名前: se0

コマンドは正常に終了しました。

接続設定

コンソール画面から、接続設定を作るのは面倒なので、WindowsUbuntuから動作中の設定をインポートするほうが速いでしょう。

VPN Client>AccountImport
AccountImport コマンド - 接続設定のインポート
インポート元ファイル名: /path/to/file

とくに、仮想Hubの名前はServer側と密接に関わってるはずです。 適当に決められないはず。

他の動作済み設定をインポートするのが確実だと思います。

接続

VPN Client>AccountConnect
AccountConnect コマンド - 接続設定を使用して VPN Server へ接続を開始
接続設定の名前: ocn

IPアドレスの割当。

tapデバイスsoftether が使うので、tap デバイスIPアドレスを割り当てる。

Softetherの場合は、接続先がDHCPしていてて自動的に割り当てがほとんどだと思う。だからDHCPから割当もらえば十分。

sudo ipconfig set tap0 DHCP

ルーティングの追加。

接続ができたら、ルーティングを追加する。

sudo ip route add 10.100.10.0/24 via 10.9.100.254 dev tap0

私は、maciproute2相当のエイリアスを提供してくれるパッケージを入れてるので、ip route add で済ませた。

疎通の確認

route を確認してー

ip route get 10.100.10.100

ping を打ち込んでー

ping 10.100.10.100

ssh で接続してみる。

ssh -vvv 10.100.10.0

切断。

接続が終われば切断する。

VPN Client>AccountDisconnect
AccountDisconnect コマンド - 接続中の接続設定の切断
接続設定の名前: ocn

設定の確認

VPN Client>AccountGet
AccountGet コマンド - 接続設定の設定の取得
接続設定の名前: ocn

項目                                 |値
-------------------------------------+-----------------------------
接続設定名                           |ocn
接続先 VPN Server のホスト名         |vpn.example.ac.jp
接続先 VPN Server のポート番号       |443
接続先 VPN Server の仮想 HUB 名      |Vpn
経由するプロキシサーバーの種類       |直接 TCP/IP 接続
サーバー証明書の検証                 |無効
接続に使用するデバイス名             |seth0
認証の種類                           |RADIUS または NT ドメイン認証
ユーザー名                           |USER@EXAPLE
VPN 通信に使用する TCP コネクション数|1
各 TCP コネクションの確立間隔        |1
各 TCP コネクションの寿命            |無制限
半二重モードの使用                   |無効
SSL による暗号化                     |有効
データ圧縮                           |無効
ブリッジ / ルータモードで接続        |無効
モニタリングモードで接続             |無効
ルーティングテーブルを調整しない     |有効
QoS 制御機能を使用しない             |無効
コマンドは正常に終了しました。

対話型の省略

対話型のCLIは便利だけど、なれてくると面倒でしかないので。

次のように、コマンドに引数を与えると、一回で実行できるショートカットとして動作する。

sudo ./vpncmd /CLIENT localhost /CMD AccountList

もともとがWindowsのCMD.exe っぽいコマンドなので、「引数」にハイフンをつけずスラッシュ(/)で指定するのがちょっとわかりにくい。macOSでもスラッシュで指定ですね。

接続切断 の省略

接続切断はぱぱっと呼び出したい。

接続は、次のようにする

sudo ./vpncmd /CLIENT localhost /CMD AccountConnect ocn

切断は、次のようにする。

sudo ./vpncmd /CLIENT localhost /CMD AccountDisconnect ocn

切断したら、クライアントを終了する

ほんとこれよく忘れるので注意です。

sudo ./vpnclient stop

参考資料

https://qiita.com/ask/items/9ff1529d228ec093aa07

*1: っていうか、ネットワーク管理の業者がこの仕様を理解できないので、macOSからL2TPできないんです。設定してもらえないんです。

OpenWrtでヘアピンNAT(NATループバック)

ヘアピンNAT(ループバック)

OpenWrtでときどき、接続できないポートがあって、不思議だなと思ってたらNATがループバックしてなかった。

設定→ネットワーク

ネットワーク→ファイアウォール→ポートフォワーディングの順にたどって該当のport forwarding についての、詳細(Advance)を見るとチェックボックスがある。このチェックボックスのチェックをするだけでオッケ。(よく忘れる)

f:id:takuya_1st:20211101223129p:plain

ヘアピンNATをiptablesで実現するとしたら

ヘアピンNAT( loopback NAT/ redirect NAT) を実現するとしたら。

PPPoEのデバイスに、DNATとSNATを噛ましてあげれば動く。

iptables -t nat -D PREROUTING -i $LAN_DEV -s $LAN_NETWORK_ADDR/24 -d $PPPOE_IPADDR -p tcp -m tcp --dport 443 -j DNAT --to-destination $TARGET

ルーターの場合SNATはマスカレードで入っていることが多いのでそのままで通る。 マスカレードしていいなら記述は不要。

LANをMASQURADE(NAPT)してないなら、SNATを書いてルーターからのパケットとしてあげる。などで対応が可能。

iptables -t nat -A POSTROUTING -o $LAN_DEV -s $LAN_NET_ADDR/24 -d $TARGET -p tcp -m tcp --dport 443 -j SNAT --to-source $ROUTER_IP

Before

たとえば、wireguard VPN経由( 172.16.4.0/24 ) のパケットがNATループバックをしてない。

root@OpenWrt:/etc/config# iptables -t nat -L  | grep 443
DNAT       tcp  --  192.168.10.0/24       ""ISP v4***  tcp dpt:https /* !fw3: atom-https (reflection) */ to:192.168.10.24:443
DNAT       udp  --  192.168.10.0/24       ""ISP v4***  udp dpt:https /* !fw3: atom-https (reflection) */ to:192.168.10.24:443
DNAT       tcp  --  172.16.4.1           ""ISP v4***  tcp dpt:https /* !fw3: atom-https (reflection) */ to:192.168.10.24:443
DNAT       udp  --  172.16.4.1           ""ISP v4***  udp dpt:https /* !fw3: atom-https (reflection) */ to:192.168.10.24:443
DNAT       tcp  --  anywhere             anywhere             tcp dpt:https /* !fw3: atom-https */ to:192.168.10.24:443
DNAT       udp  --  anywhere             anywhere             udp dpt:https /* !fw3: atom-https */ to:192.168.10.24:443

After

VPN経由( 172.16.4.0/24 )のパケットも443 でループバックするようになった。

root@OpenWrt:~# iptables -t nat -L  | grep 443
DNAT       tcp  --  192.168.10.0/24       ""ISP v4***  tcp dpt:https /* !fw3: atom-https (reflection) */ to:192.168.10.24:443
DNAT       udp  --  192.168.10.0/24       ""ISP v4***  udp dpt:https /* !fw3: atom-https (reflection) */ to:192.168.10.24:443
DNAT       tcp  --  172.16.4.0/24        ""ISP v4***  tcp dpt:https /* !fw3: atom-https (reflection) */ to:192.168.10.24:443
DNAT       udp  --  172.16.4.0/24        ""ISP v4***  udp dpt:https /* !fw3: atom-https (reflection) */ to:192.168.10.24:443
DNAT       tcp  --  172.16.4.1           ""ISP v4***  tcp dpt:https /* !fw3: atom-https (reflection) */ to:192.168.10.24:443
DNAT       udp  --  172.16.4.1           ""ISP v4***  udp dpt:https /* !fw3: atom-https (reflection) */ to:192.168.10.24:443
DNAT       tcp  --  anywhere             anywhere             tcp dpt:https /* !fw3: atom-https */ to:192.168.10.24:443
DNAT       udp  --  anywhere             anywhere             udp dpt:https /* !fw3: atom-https */ to:192.168.10.24:443

ループバックの設定

ループバックの設定は、config でも行える。

コマンドからSMTPでメールを送るテストを手軽にやる。

メールサーバーの疎通テストを簡単にやりたい

メールサーバーに接続して送信するのを定期的にチェックしています。

昭和平成のレトロ家庭用の機器(FAX)などがメールに対応しててもSMTPSに非対応なので、Raspiでプロキシしていますが、疎通テストや認証テストが面倒なので、自動的にチェックしたい

crontab にかけるくらい単純にしたい。

curlSMTPを送信するのが非常に楽

SMTP over SSL の場合

curl --url 'smtps://smtp.gmail.com:465' \
  --ssl-reqd \
  --mail-from 'example@gmail.com' \
  --mail-rcpt 'edm-user@example.com.com' \
  --upload-file mail.txt  \
  --user 'developer@gmail.com:your-accout-password'

ローカル用の認証・SSLなしSMTPの場合

curl -v --url 'smtp://192.168.1.1:25255' \
  --mail-from from@example.com \
  --mail-rcpt  to@example.com \
  --form-string content=hello

curl でやるのが一番ラク

telnet で接続確認して、そのまま送ると自動化できない。

expect で telnet するのは流石に違う。

python でsmtplib などを使うのもいいが管理が煩雑だ。

ssmpt をインストールするのも面倒だ。

curl は比較的にどこにでも入ってる。

curl ならコマンドがどこにでもあるし、crontab に書くのもらくちんだった。

参考資料

https://blog.edmdesigner.com/send-email-from-linux-command-line/

うるさいHDDを黙らせる/ hdparm でHDD電源オフでスピン停止にする

HDD が睡眠を妨げる。

いまどきHDDなんかやめてSSDにしろと言われそうなのですが。SSD・HDDを1TBあたりの単価を考えると8倍近い。 そこそこ安価にデータをアーカイブするとしたらHDDの効率がいいわけです。

アーカイブなのでそんなに頻繁にアクセスしないので、電源を切っておけばいいのですが、取り外してしまうと使いたいときに使えないので死蔵することになり、データを置いておく意味すら希薄になる。

そこで、スピンダウンをして静かにしてもらえばいいのではないかと。

hdparm でスピンオフ時間を設定できる。

hdparm を使えば、スピンをオフ時間を設定できるらしい。

takuya@:~$ sudo hdparm -S 25  /dev/sd*

/dev/sda:
 setting standby to 25 (2 minutes + 5 seconds)

/dev/sdb:
 setting standby to 25 (2 minutes + 5 seconds)

/dev/sdc:
 setting standby to 25 (2 minutes + 5 seconds)

/dev/sdd:
 setting standby to 25 (2 minutes + 5 seconds)
 

即時オフ

今すぐオフもできる。恐ろしいので、やらないけど。

sudo hdparm -S 0 /dev/sda1

sudo vim /etc/hdparm.conf

設定の永続化

 command_line {
  hdparm -S 25 /dev/sda
  hdparm -S 25 /dev/sdb
  hdparm -S 25 /dev/sdc
  hdparm -S 25 /dev/sdd
}

注意点

HDDのスピンダウンとアップを頻繁に繰り返すと故障の原因になりやすい。 また、自動チェックツール(smartd)やデフラグでアップになる可能性が高い。

現在の状態を確認する。

hdparm -C で状態を確認できる。

takuya@:~$ sudo hdparm -C /dev/sd*

/dev/sda:
 drive state is:  active/idle

/dev/sdb:
 drive state is:  active/idle

/dev/sdc:
 drive state is:  active/idle

/dev/sdd:
 drive state is:  active/idle

/dev/sde:
 drive state is:  active/idle

/dev/sdf:
 drive state is:  active/idle

今すぐスリープ

今すぐスリープできる。

sudo hdparm -Y /dev/sd*

スリープになったの確認する

sudo hdparm -C /dev/sd*  # ちょっと時間がかかる。

smartmontools が起動させてしまうらしい。

しかし、HDDの電源をオフでも、smartd が起こしてしまうとのこと https://www.systemworks.co.jp/ex_spindown.php

たとえば、3日おきくらいにしておくとか。

takuya@borane:~$ cat /etc/default/smartmontools
# 2021-11-18 by takuya 3日おきくらい
smartd_opts="--interval=259200"

電源オフは茨の道。

どうしても停止させたいときは止められることはわかるが、あまり止めるべきでもないのかもしれない。

予備ディスクはスタンバイでもいいかも

接続してるだけの待機ディスクは、スタンバイにしてもいいと思う。

参考資料

tarに纏めながら、rclone の転送を同時にやる

tar しながら転送も同時にやる。

tar zcvf - <dir> | rclone rcat remote:path/to/file

rclone "rcat"

rcat を使えば、パイプで処理するみたいに投げられる。

https://rclone.org/commands/rclone_rcat/

echo "hello world" | rclone rcat remote:path/to/file
ffmpeg - | rclone rcat remote:path/to/file

使い所

バックアップをとったりするとファイル数が多くなりがちで、ダウンロードや同期にAPI呼び出しが多くなりタイムロスが多い。 また、google drive のように symbolic link に非対応なクラウド・ストレージに転送すると情報が欠損するためtar にまとめて転送したほうがなにかと使い勝手がいい。

同様に圧縮しながら転送

gzip や xz を使って圧縮しながら転送すれば、処理も楽である。

mysqldump と組み合わせると。

一時ファイルを作らずに直接rclone の先にバックアップ取れるから快適じゃないか。

たとえば、こんな感じでmysqldump | gzip | rclone をパイプに纏めてやる

sudo \
 mysqldump --single-transaction  \
 -h localhost -u takuya --password=XXXXX takuya-database  2>/dev/null \
 | gzip -  | \ 
 rclone gdrive:takuya-server/backup/mysqldump.sql.gz > /dev/null

gdriveなら30日間のファイル履歴が残るので、バックアップをローテーションして消さなくても良い。最強じゃないか。

rclone で圧縮しながら dd

ddも rclone で圧縮しながらできます。

sudo dd if=/dev/sdg bs=16M --progress | \
  gzip -9 -c  | \
 rclone --bwlimit=5M rcat gdrive:/backup.img.gz

ディスク容量がカツカツでも dd / ddrescue できるので嬉しい。

2021-11-26

rclone と mysqldump の組み合わせについて追記。

MacOSの濁点・半濁点を解決する。

macOS で作られたファイルの濁点半濁点問題。

ファイル名がUTF-8といえども、mac は濁点を合成文字として扱うので、Linuxで読むと面倒が起きる。

sudo convmv -f utf-8 -t utf-8 -r --notest --nfc ./*

ディレクトリ内部を再帰的に処理される。 find と組み合わせなくていいのが便利。

逆に言えば、内部全部が対象なので、うっかりしないように注意。

rsync 時にまとめてやる

rsync -a --iconv=utf-8-mac,utf-8 

rsync 時にまとめてやっておくと便利だと思われる。

ユニコード正規化

ユニコードで、macOSの日本語はNFDの亜種が使われている。

たとえば、macで作った<パ>は2文字で構成されている。

"パ".each_codepoint{|e| p e.to_s(16) }.map
"30cf"
"309a"

文字コードから文字のコードポイントを取得すると、2文字で構成されていることがわかる。

Windowsで作った「パ」は1文字で構成されている。

"パ".each_codepoint{|e| p e.to_s(16) }
"30d1"

この文字の違いは、ブラウザなど対応したソフトウェアで表示自体は同じだし、ユニコードとして特に問題がないので間違いではない。

けど、非対応なソフトウェアで表示すると、表示が乱れる。カーソル位置がおかしくなる

特に問題がでてくるのがWindowsのターミナルである。本当に不便なのです。 個人的な意見を言えば、日本語の取り扱いは、日本政府による規制と標準化が求められると思います。

apt でバージョン指定でアップグレード・インストール/apt list -a ですべてのバージョンを確認

/## apt install でバージョン指定でインストール

やりかた

sudo apt install パッケージ名=バージョン名

sudo apt install gitlab-ce=13.12.12-ce.0

apt install は指定バージョンまでアップグレードできます。

apt コマンドは アップグレードもインストールも同じだし当たり前なんだけど。

sudo apt install --upgrade gitlab-ce=13.12.12-ce.0
sudo apt upgrade gitlab-ce=13.12.12-ce.0

バージョン指定ができますね。

バージョン一覧を取得する

インストール対象となるバージョンを探すには、まずバージョン一覧を取得して選択する必要があります。

sudo apt list --upgradable -a gitlab-ce

または apt-cacheから

sudo apt-cache showpkg gitlab-ce

アップグレード時のコツ

単純にアップグレードしようとして、sudo apt upgrade アップグレードコマンドを打ち込んだとき

unpack でエラーになったりする。

dpkg: アーカイブ /var/cache/apt/archives/gitlab-ce_14.3.3-ce.0_amd64.deb の処理中にエラーが発生しました (--unpack):

そういうときに、一気にバージョンをあげようとせずに、一つずつバージョンを上げて試していいくことで解決する。

例に上げた、gitlab のバージョンアップは、postgresql 11 が必須になっていて sudo gitlab-ctl pg-upgrade をやれと、12→13 のときに出てきた、 12→14だと表示はもうなかった。

このように、最新バージョンに一気に挙げずに、バージョンを少しずつアップグレードしていくことで問題点が洗い出される事例は多い。

バージョン指定はgitlab-ce でよく使う。

gitlab-ceは、一気にバージョンを上げると、エラーになる。なので、ちょっとずつ上げていく

バックアップとって、バージョンを指定して、バージョンアップする。

sudo gitlab-backup create
sudo apt install --upgrade gitlab-ce=12.10.14-ce.0

gitlabについては、upgrade時にバックアップは自動取得されること「も」あるが、油断しちゃだめ。

ssh 秘密鍵のパスフレーズを変更(解除)する

ssh秘密鍵のパスワード変更

パスフレーズを変更する。(パーミッション変更が必要)

chmod 600  ~/my.ssh.id_rsa
ssh-keygen -p -f  ~/my.ssh.id_rsa

sshパスフレーズを解除する

パスフレーズを解除するときは、Enterを押す。空のパスワードを設定する。

Enter old passphrase:
Enter new passphrase (empty for no passphrase):
Enter same passphrase again:

以前の投稿

秘密鍵のパスフレーズを解除してパスフレーズなしの秘密鍵を作る。 - それマグで!

ookla のスピードテストが安定しないうえにサーバー指定できなくなった

定期的に speedtest で速度測定してる

もうかれこれ2年位毎日スピードテストしてはログをためてたんだけど、サーバー指定ができなくなった。

いままでは、speedtest-cli でサーバー指定ができたのだけど、2021/08/29から最寄りのサーバーしか接続できなくなった。

f:id:takuya_1st:20211012032800p:plain

測定しすぎと怒られそうではあるが。。。ユーチューブが普及してインターネットが遅くなるピーク時間帯の速度変化を観察することで、混雑時間帯を避けて、apt update / upgrade やdocker の更新など個人で使うにはとんでもない量のパケットを流し続ける負い目がどうしてもあったので、速度測定の結果をダウンロードやアップロードの負荷分散に利用していた。どの時間帯が混んでいるか、PPPoEを複数ISPで接続して測定したんですが、統計的にデータを取るためには測定結果ブレ幅が大きいので、サーバー指定してたわけです。しかしできなくなった。

オフィシャルのクライアントなら指定できる

f:id:takuya_1st:20211012033521p:plain

speedtest-cli ではなく、オフィシャルのspeedtestコマンドを使えばいまでもID指定は可能なのですが。いつ終わるかわからないし、有志のCPUパワーなのでずっと気が引けてたわけで。これを期に乗り換えようと思ったわけです。

代替のスピードテスト

そこで、Cloudflareのスピードテストがサービス開始していたことを思い出して、そのクライアントを探したら・・・あった

私は断続的に測定して結果の変化を知りたいので、最高速度が知りたいわけでもなく。継続的に安定した測定結果を求めていた。

たぶんもっといい方法はある。VPS借りてHTTPの転送速度をCurlで測るとかしとけばだいぶ正確に出るとは思うけど。管理するサーバーが増えるのは困るし。どこかの画像をずっとダウンロードし続けるのも気が引ける。

cloudflareのスピードテスト用のcli

speed-cloudflare-cli - npm

takuya@~$ npm i -g speed-cloudflare-cli

added 1 package, and audited 2 packages in 3s

found 0 vulnerabilities
takuya@~$ speed-cloudflare-cli
 Server location: Tokyo (NRT)
         Your IP: 27.230.xxxxx (JP)
         Latency: 48.63 ms
          Jitter: 2.80 ms
     100kB speed: 24.94 Mbps
       1MB speed: 61.60 Mbps
      10MB speed: 189.32 Mbps
      25MB speed: 213.41 Mbps
     100MB speed: 274.18 Mbps
  Download speed: 207.27 Mbps
    Upload speed: 29.66 Mbps
takuya@~$

いけそう

grep の後方参照の代替案 5つ

grep では 後方参照ができないので、代替案を考えることになる。

方法1基本的な方法 -o

マッチした箇所だけを取り出す -o を使って、マッチした箇所だけを取り出す。

cat out.txt  | \grep -Po  'Abc.*Xyz'

方法2 先読み+あとよみ

先読み・後ろ読みにマッチした箇所だけを取り出す -o を組み合わせる。

cat out.txt  | \grep -Po  '(?<=Abc).*(?=Xyz)'

方法3 perlruby などワンライナーを使う

もはや、grep ではないが、代替案としては行ける

cat out.txt  | ruby -pe 'sub(/^Abc(.*)Xyz/, "\\1")'

方法4 sed で置換する

もはや、grep ではない。が代替案としては行けるし、sedは手軽に使える。

cat out.txt | sed  -nr 's/Abc(.+)Xyz/\1/p' 

ただし、sedでは、非マッチ箇所が残る。 sedはマッチした箇所を置換するだけなので、マッチしない箇所は出力される。

そこで、-nをつけて、マッチした箇所だけを表示するようにする。

方法5 bashの機能を使う。

[[ takuya =~ taku(.+) ]]
echo ${BASH_REMATCH[@]}

bash に正規表現のマッチングが追加されている。マッチした箇所をBASH_REMATCH変数で取り出せるので、後方参照の代わりになる。

後方参照を使いたいような場面はシェルスクリプトを作ってるときだろうから bash正規表現の各種機能で事足りることがほとんどである。

感想

grep正規表現と後方参照の代替は、「後方参照」を「置換」と考えて、sedで行うのがベターだと思われる。

grep でマッチした箇所を取り出す -o などと併せて覚えおけば、ちょっとしたフィルタ処理やデータを整形するときに使えるのではないかと思う。

後方参照=置換と考えるのが大事。マッチした箇所を取り出す。だと限界がある。

2023-05-23

bash rematchを追加