それマグで!

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

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

ubuntu を4kディスプレイで拡大率125%や150%などの任意解像度をwindowsやMacみたいに選ぶ

4K モニタを使っていると、しんどい。

ubuntu で 4k ディスプレイを使っていると、解像度が細かすぎてしんどい。

windows 10 からは拡大率150% などが選べるが、 ubuntu はデフォルト設定では 200%/100%しか選べなかった。

125%と150% を有効にする。

gsettings で 実験的機能を有効にしてあげると、解像度の拡大倍率を指定できて、MacOSretina モードみたいなことができるようになる。

gsettings set org.gnome.mutter experimental-features "['scale-monitor-framebuffer']"
gsettings set org.gnome.mutter experimental-features "['x11-randr-fractional-scaling']"

設定するとこの通り、150%が出現する。これで快適になる。

f:id:takuya_1st:20191021180026p:plain
解像度

もとに戻すとき

もとに戻すには reset を使う

gsettings reset org.gnome.mutter experimental-features

参考資料

https://www.linuxuprising.com/2019/04/how-to-enable-hidpi-fractional-scaling.html?m=1

NetworkManagerがunmanaged(管理なし)になった問題を解決した

network-manager で管理できない。

network-manager で unmanaged になって、ubuntu desktop (gnome) からネットワークが管理できなかった。

依存関係が多くて、問題がわかりにくい。

ubuntu は 1年前から、 netplan が導入されているので、ubuntu server は systemd-networkd で管理、 ubuntu desktop は NetworkManager で管理することになっている。

それでは、/etc/network/interfaces はどうなったのか?

network-manager のときは、 network-manager が /etc/network/inteface をparsing して管理デバイスを見つけた上で除外し、残ったデバイスを管理するようになっている。

ただし、この設定はキャッシュされるらしい。(マジだったら、コレはホントめんどくさいわ)

networkd のときは、 networkd の起動後に /etc/network/intefaces を取得して管理する。こっちも面倒くさい。

デスクトップubuntu では networkd はいらない

使ってもいいんだけど、依存関係が多くて面倒くさいので、除外して切り分ける

sudo systemctl stop systemd-networkd.service
sudo systemctl disable systemd-networkd.service
sudo systemctl mask systemd-networkd.service

netplan の設定をシンプルにする。

netplan は networkmanager を使う設定にして、シンプルにする。

takuya@:~$ cat /etc/netplan/01-netcfg.yaml 
network:
  version: 2
  renderer: NetworkManager

netplanの設定を再生成してあげる

sudo netplan generate

これで、余計なものは動かなくなる。

ただし、場合分けのために除外し過ぎくらい除外してる。なので、netplan apply すら動かない。

この辺は、正直言ってubuntu の問題だろうなぁ。 networkmanager を指定してるのに 一旦 networkd を経由しようとしている。

takuya@:~$ sudo netplan generate 
takuya@:~$ sudo netplan apply 
Failed to start systemd-networkd.service: Unit systemd-networkd.service is masked.
Traceback (most recent call last):
  File "/usr/sbin/netplan", line 23, in <module>
    netplan.main()
  File "/usr/share/netplan/netplan/cli/core.py", line 50, in main
    self.run_command()
  File "/usr/share/netplan/netplan/cli/utils.py", line 130, in run_command
    self.func()
  File "/usr/share/netplan/netplan/cli/commands/apply.py", line 44, in run
    self.run_command()
  File "/usr/share/netplan/netplan/cli/utils.py", line 130, in run_command
    self.func()
  File "/usr/share/netplan/netplan/cli/commands/apply.py", line 153, in command_apply
    utils.systemctl_networkd('start', sync=sync, extra_services=netplan_wpa)
  File "/usr/share/netplan/netplan/cli/utils.py", line 82, in systemctl_networkd
    subprocess.check_call(command)
  File "/usr/lib/python3.7/subprocess.py", line 363, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['systemctl', 'start', '--no-block', 'systemd-networkd.service']' returned non-zero exit status 1.

NetworkManager の設定は多ファイルに分割されている

NetworkManager の設定ファイルは、/etc/NetworkManager だけでなく、 /usr/lib/NetworkManager などにデフォルト設定あったりして、それらがマージされて /etc/NetworkManager で上書きするようになっている。

takuya@:~$ sudo NetworkManager  --print-config
# NetworkManager configuration:
 /etc/NetworkManager/NetworkManager.conf (lib: 10-dns-resolved.conf, no-mac-addr-change.conf)
(run: netplan.conf) 
(etc: 10-globally-managed-devices.conf, default-wifi-powersave-on.conf)


## 略

/etc/NetworkManager で設定ファイルを見てもすべてが記載されているわけでじゃないので、 --print-config で最終的な設定を確認するのがポイント

ifupdown を使わないようにする。

ifupdown は /etc/network/interfaceを管理するので、 ifupdown も切り分けのために一旦無効化する。

sudo apt uninstall ifupdown
sudo apt uninstall ifupdown2
sudo apt uninstall netscript-2.4 

NetworkManager.conf でunamanged デバイスをすべて上書きして無効化する。

設定方法は、いくつか考えられるのだけど、umamanged になる問題を解決するために、すべての設定をOFFにしたり消していく。

takuya@:~$ cat /etc/NetworkManager/NetworkManager.conf 
[main]
#plugins=ifupdown,keyfile
plugins=keyfile
dns=default

[keyfile]
unmanaged-devices=
#[ifupdown]
#managed=true

[device]
wifi.scan-rand-mac-address=yes

ちなみに、ifupdownのmanaged は ifup/ifdown で管理される /etc/network/intefacesを nmcli で管理するかどうか。

restart する

あれこれ、余計なものを排除した結果動くようになる、

takuya@:~$ sudo systemctl status network-manager.service 
● NetworkManager.service - Network Manager
   Loaded: loaded (/lib/systemd/system/NetworkManager.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2019-10-21 17:20:33 JST; 10s ago
     Docs: man:NetworkManager(8)
 Main PID: 4474 (NetworkManager)
    Tasks: 4 (limit: 4915)
   Memory: 4.0M
   CGroup: /system.slice/NetworkManager.service
           └─4474 /usr/sbin/NetworkManager --no-daemon

10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9682] device (enp3s0): state change: ip-config -> ip-check (reason 'none', sys-iface-state: 'assume')
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9809] device (enp3s0): state change: ip-check -> secondaries (reason 'none', sys-iface-state: 'assume')
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9813] device (enp3s0): state change: secondaries -> activated (reason 'none', sys-iface-state: 'assume')
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9819] manager: NetworkManager state is now CONNECTED_LOCAL
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9832] manager: NetworkManager state is now CONNECTED_SITE
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9834] policy: set '有線接続 1' (enp3s0) as default for IPv4 routing and DNS
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9876] device (enp3s0): Activation: successful, device activated.
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9885] manager: NetworkManager state is now CONNECTED_GLOBAL
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9892] manager: startup complete
10月 21 17:20:34 j5005 NetworkManager[4474]: <info>  [1571646034.0348] bluez5: NAP: added interface 00:09:DD:50:6C:BF

管理下に置かれる

takuya@:~$ nmcli d
DEVICE  TYPE      STATE     CONNECTION 
enp3s0  ethernet  接続済み  有線接続 1 
lo      loopback  管理無し  --         

unmanaged だったのが

f:id:takuya_1st:20191021172309p:plain

managed になる。

f:id:takuya_1st:20191021172202p:plain

なんでこんなにめんどくさいのか

過渡期とはいえ、systemd 関連の更新と整合性を保つために、あれこれ機能が追加されている。

あれこれ過渡期だからでしょうね。 nmcli や netplan を諦めて /etc/network/interfacesだけに戻すか、素直にnetworkd だけにしたほうが将来的に楽なのかなぁ。

今回驚いたのは ifup/down のコマンドを提供するパッケージが3つもあったことだった。ネットワーク周りはカオスですね。

NetworkManager でDHCPで取得したDNSの設定を/etc/resolv.confに書き込む

ubuntu デスクトップのネットワーク設定は NetworkManagerから

Ubuntu のネットワーク周りはカオス。というか、最近のLinuxのネットワーク周りはディストリ間でsystemdによる共通化を受容している段階なのでややこしい。

Ubuntuのデスクトップ版は主にNetworkManagerで管理しているんだけど、DNSの設定は、resolv.confに直接書かずにリンクになってたりする。これがちょっと不満なので、直接 /etc/resolv.confに書き込んでほしい。

/etc/NetworkManager/NetworkManager.conf

[main]
plugins=ifupdown,keyfile
dns=default

設定したら再起動

再起動して、DNS設定をDHCPから取得し直す。

sudo systemctl restart network-manager

もし。/etc/resolv.confがsymlinkになって利すると面倒なので、いったん/etc/resolv.confを空にしておくといいかも

sudo rm /etc/resolv.conf;
sudo touch /etc/resolv.conf

再起動後は、直接取れる。

再起動後、DHCPで割り振られたDNSサーバーが直接参照できるようになる。

takuya@:~$ ll /etc/resolv.conf
-rw-r--r-- 1 root root 89 2019-10-11 15:38 /etc/resolv.conf

/etc/resolv.conf

# Generated by NetworkManager
search local
nameserver 192.168.2.1
nameserver 192.168.2.5

network-managerのDNS設定

https://qiita.com/onokatio/items/af0035d1563acbbfeed2

これによると、次のようになる。

  • dnsモード 振る舞い
  • default 取得したDNSサーバーをそのまま使います。
  • dnsmasq キャッシュ用にdnsmasqをサブプロセスとして起動します。DNSサーバーは127.0.0.1を使います。
  • unbound 上のunboundバージョン
  • systemd-resolved 上のsystemd-resolvedバージョン
  • none NetworkManagerはDNSに関して何もしません。また次に書いてあるrc-managerも無効になります。

ネットワーク周りは面倒くさい。

dns の設定だけでも、

  • network-manager
  • /etc/resolv.conf
  • /etc/resolvconf.conf
  • systemd networkd-resolved

と、相互に依存しながら編集してるので、注意しないとデフォルト設定がどこに流れているのかわからなくなるよね。。。

gitでリモートブランチをローカルブランチにチェックアウトする。(githubプルリクを手元にコピー

リモートにあるブランチをローカルに持って来たい

たとえば、github のプルリクなど、リモートのgit branch から自分の手元に、同じものを取り出したいときがあります。

git のリモートブランチを確認します。

git branch -a | \grep remote

たとえば、次のようにほしいブランチ名を確認します。

takuya@i$ git branch -a | \grep remote  | grep add
  remotes/origin/add_table_column
  remotes/origin/add_notify
  remotes/origin/createAddUpdateModel

これで、必要なリモートブランチ名を確認出来ました。github のプルリクをブランチベースでやっていると、プルリクに表示されてます。

git のリモートブランチが見つからない場合、

リモートブランチの名前が見つからないときは、次のように fetch します。

git fetch 

リモートブランチの名前が見つからないなんて、そんなことを起きるの?と疑問を感じるかもしれません。リモートブランチはfetch しない限り出てきません。gitは分散レポジトリなのでリモートブランチの更新を取り出す必要があります。

ローカルブランチ名を指定して、リモートブランチをコピー・チェックアウトします。

次のように、リモートブランチを取り出し、ローカルブランチの名前を付けます。別の名前も可能ですが、同じ名前にしておくのが無難だと思います。

takuya@$ git checkout -b  add_notify origin/add_notify

Branch 'add_notify' set up to track remote branch 'add_notify' from 'origin'.
Switched to a new branch 'add_notify'

これで、リモートブランチをローカルに取り出してソースコードを見ながら、実験できますね。

同じ名前を使うのであれば、次のように省略することも可能です。

git checkout -b origin/add_notify

というか、省略した此方を一般的に記事で紹介されるのではないでしょうか。ただこちらはローカルとリモートの対応がわかりづらく、ミスを誘発しやすいので最初は localと remote origin の両方を指定したほうがいいのかもしれません

さらなる短縮化が出来て

もちろん、さらなる短縮化が出来て、無意識のうちにこれを使ってる可能性があります。私もこれです。

Branch 'add_notice' set up to track remote branch 'add_notice' from 'origin'.
Switched to a new branch 'add_notice'

checkout のメッセージをよく読むと、
remote branch の add_notice が origin にあるのでそこから、追跡してブランチをセットアップするよ。(Branch 'add_notice' set up to track remote branch 'add_notice' from 'origin'.) と書いてありますね。つまり、このメッセージが出てきたらOK、省略したcheckout でもちゃんとoriginから取り出せたことが解るようです。

参考資料

Git - リモートブランチ

systemd の タイマーは enable してもstart をしないと動かない

systemd でタイマーを作ってみたんですよ。タイマーが動かないので悩んでたんです。

systemd でタイマーを作って、enableして見たんだけど。動かないんですよ。

タイマーを作る手順

  • service 作って
  • timer 作って service を起動する
  • start してチェック
  • enable する。

という手順なんだけど、start コマンド実行が大事。 timer はstart しないと動かないとか盲点でした。

dig するだけのサービスを試しに laravel で作ってみて、それでタイマーを動かすことに。

takuya@:~$ ln -sr  laravel_checkip.service /etc/systemd/system/
takuya@:~$ ln -sr  laravel_checkip.timer    /etc/systemd/system/

サービスファイルをチェックする。

takuya@:~$ sudo systemctl start laravel_checkip.service

サービスをenableにして、タイマーをenable にする。

takuya@:~$ sudo systemctl enable laravel_checkip.service
takuya@:~$ sudo systemctl enable laravel_checkip.timer

状態を確認する。

タイマーはenable してもそのままでは動かない。

takuya@:~$ sudo systemctl list-timers --all
NEXT      LEFT          LAST      PASSED       UNIT                         ACTIVATES
n/a       n/a             n/a          n/a          laravel_checkip.timer        laravel_checkip.service

8 timers listed.

start すると動き出す。

なんでかわからんけど start すると 動き出した。enable だけでいいと思ってたけど記憶違いだったらしい

takuya@:~$ sudo systemctl start  laravel_checkip.timer

動き出した。

takuya@:~$ sudo systemctl list-timers --all
NEXT          LEFT         LAST       PASSED       UNIT                                  ACTIVATES
Wed 2019-09-18 21:01:56 JST  56min left   n/a         n/a               laravel_checkip.timer        laravel_checkip.service

8 timers listed.
takuya@:~$

systemd でタイマー作るときは start timer を忘れない。

SystemCtrlのタイマーを作るときは、この手順をする。

takuya@:~$ sudo systemctl enable  laravel_checkip.service
takuya@:~$ sudo systemctl enable  laravel_checkip.timer
takuya@:~$ sudo systemctl start  laravel_checkip.timer

laravel のmodel を 外部から使う

laravel の Eloquent のモデルを別のプロジェクトからぱぱっと使う。

Consoleとかあるし、API作れば実現はできる。でも既存のものと組み合わせるときは、DBを直接書き換えたほうが早い時がある。

本当はプロジェクトの外部から直接触るのは良くないと思うし、プロジェクト側にAPIを作ったり、メンテナンス用のコマンドをプロジェクト内部につくったり、メンテナンス用のデータ復旧をMigration や Fixtgure / UnitTestと同様に作るべきなんだろうけど。

<?php
  /// laravel の Eloquent を外部から使う設定

// 必要なものをロード
  require_once __DIR__.'/vendor/autoload.php';
// DB の接続情報をいれる
  $capsule = new Illuminate\Database\Capsule\Manager();
  $capsule->addConnection([
                            "driver"   => "sqlite",
                            "database" => __DIR__."/database/database.sqlite",
                          ]);
  $capsule->setAsGlobal();
  $capsule->bootEloquent();

  ///
  /// AccessLogs モデルを保存してみる。
  require_once __DIR__.'/app/Model/AccessLogs.php';
  $al = new  App\Model\AccessLogs();
  $al->body = "Hello from  External World ";
  $al->save();

名前空間の解決

<?php
// 必要なものをロード
  require_once __DIR__.'/vendor/autoload.php';

今回は、$PROJECT_HOME/sample.php においたのでこのように書いている。

ただしくは、次のautoloadをlaravel で使っているのでこれを使う。(詳しくは laravel/public/index.php を見ればわかる。

<?php
$PROJECT_PATH/vendor/autoload.php

DB の解決

必要なロードが出来たので、DBを使うための初期設定をする。

ここでの目標は bootEloquent(); を実行することです。

<?php

// DB の接続情報をいれる
  $capsule = new Illuminate\Database\Capsule\Manager();
  $capsule->addConnection([
                            "driver"   => "sqlite",
                            "database" => __DIR__."/database/database.sqlite",
                          ]);
  $capsule->setAsGlobal();
  $capsule->bootEloquent();

最後にモデルをロードして利用する。

laravel で作っている model を 明示的にロードして、new して save する。

<?php
  /// AccessLogs モデルを保存してみる。
  require_once __DIR__.'/app/Model/AccessLogs.php';
  $al = new  App\Model\AccessLogs();
  $al->body = "Hello from  External World ";
  $al->save();

これですべて解決する。

シェルスクリプトで実行中の関数名を関数内部から知る(自分自身の関数名)

自分自身の関数の名前を知りたい。

関数名は、関数名を表す変数に入っている(BASHで確認)

echo ${FUNCNAME[0]}

これを使うと、自分自身の関数名を実行中に参照できる。

takuya@Desktop$ function sample() { echo ${FUNCNAME[0]} ;  }; sample
sample

便利。

なんで自分自身の関数名を知る必要があるのか。

実行後に関数を消したいから

関数を使い終わったら片付けたいときがあります。一時的な関数として、処理をブロックに分けるだけの目的で使うことがります。

function sample001() {
 # なにか処理
 
 ## 処理が終わったら自分自身消す。
 unset ${FUNCNAME[0]} ;
};

これを実行するとこのようになります。 実行後は関数が消えています。これで名前を汚さずに自分の関数をシェルスクリプトで使えます。

takuya@Desktop$ function sample001() {
>  echo ${FUNCNAME[0]} ;
>  unset ${FUNCNAME[0]} ;
> };
takuya@Desktop$ sample001
sample001
takuya@Desktop$ sample001
-bash: sample001: コマンドが見つかりません

なぜ名前を調べて消す必要があるのか。

bashrc のような dotfile で環境設定をする処理に使います。

環境設定するsample.sh をシェルスクリプトで書いた場合

function sample001() {
    ## なにか処理
    echo 環境設定をした
 };
sample001

source すると関数がENVに残ってしまう。

$ source sample.sh
$ sample001

そのために、長い処理をブロック単位に分けて書くとき無駄に関数を設定すると、unset を忘れがちになってしまう。

そこで、source するシェルの環境設定ファイルを書く場合に関数を自分自身で unset しておけば汚さずにすむ

function sample001() {
    ## なにか処理
    echo 環境設定をした
    ## 使い終わったら消す
    unset ${FUNCNAME[0]} ;
 };
sample001
$ source sample.sh
$ sample001 # not found 

このように、自分自身の関数名を知るノウハウは、シェルスクリプトで環境設定をブロック単位で管理することがしやすくなるので本当に便利りだ!!とおもった

nginx でSSHをプロキシして転送する 443 の再利用も可能

nginx でSSHの接続を転送することが出来ます。

nginx には ストリームをそのまま転送することが出来る機能があるので、TCP・IPのポートフォワードができて、ルーター的な動作が出来ます。

nginx.conf

stream {
  upstream ssh {
    server 192.168.2.8:22;
  }
  server {
    listen 2222;
    proxy_pass    ssh;

  }
}

なんと443 を再利用することも可能

まだ試してないのですが、 443 を ssh / ssl の両方で待ち受けることも可能になってるようです。今使ってる グローバルIP上の nginx が非対応なので試すのは少し先になりそう

Run Non-SSL Protocols on the Same Port as SSL in NGINX 1.15.2

関連資料

2022-04-08更新

NGINX で ssh TLSを同時に扱うときは次のようにします。

https://takuya-1st.hatenablog.jp/entry/2022/04/06/005007

参考資料

lvm 関連のコマンドをsudo で使えるように sudoers を編集する

lvm 関連のコマンドは root のみ

lvm コマンドを実行したいと思っても、root に制限されているので、使えないことがあり困ったので、一般ユーザーに開放することにした。

sudoers に許可したいコマンドのフルパスを列挙すればいい。

Cmnd_Alias LVM = /sbin/lvchange,/sbin/lvconvert,/sbin/lvcreate,/sbin/lvdisplay,\
                 /sbin/lvextend,/sbin/lvm,/sbin/lvmchange,/sbin/lvmconf,/sbin/lvmdiskscan,\
                 /sbin/lvmdump,/sbin/lvmetad,/sbin/lvmsadc,/sbin/lvmsar,/sbin/lvreduce,\
                 /sbin/lvremove,/sbin/lvrename,/sbin/lvresize,/sbin/lvs,/sbin/lvscan,\
                 /sbin/pvchange,/sbin/pvck,/sbin/pvcreate,/sbin/pvdisplay,/sbin/pvmove,\
                 /sbin/pvremove,/sbin/pvresize,/sbin/pvs,/sbin/pvscan,/sbin/vgcfgbackup,\
                 /sbin/vgcfgrestore,/sbin/vgchange,/sbin/vgck,/sbin/vgconvert,\
                 /sbin/vgcreate,/sbin/vgdisplay,/sbin/vgexport,/sbin/vgextend,\
                 /sbin/vgimport,/sbin/vgmerge,/sbin/vgmknodes,/sbin/vgreduce,\
                 /sbin/vgremove,/sbin/vgrename,/sbin/vgs,/sbin/vgscan,/sbin/vgsplit

takuya   ALL=(ALL) NOPASSWD: LVM

sudo lvs で使える。

sudo pvs 

コマンド一覧作り方

lvm 関連のコマンドは、lvm のサブコマンドや

takuya@:~$ lvm
  WARNING: Running as a non-root user. Functionality may be unavailable.
lvm> help
  pvremove        Remove LVM label(s) from physical volume(s)
  pvs             Display information about physical volumes
  pvscan          List all physical volumes
  segtypes        List available segment types
  systemid        Display the system ID, if any, currently set on this host
  tags            List tags defined on this host
  vgcfgbackup     Backup volume group configuration(s)
  vgcfgrestore    Restore volume group configuration
  vgchange        Change volume group attributes
  vgck            Check the consistency of volume group(s)
  vgconvert       Change volume group metadata format
  vgcreate        Create a volume group

sbin の中で lvm にエイリアスしているものを列挙すれば見つけられる、

takuya@:~$ ll /sbin/ | grep lvm
107:lrwxrwxrwx 1 root root      3 2017-03-18 01:29 lvchange -> lvm
108:lrwxrwxrwx 1 root root      3 2017-03-18 01:29 lvconvert -> lvm
109:lrwxrwxrwx 1 root root      3 2017-03-18 01:29 lvcreate -> lvm
110:lrwxrwxrwx 1 root root      3 2017-03-18 01:29 lvdisplay -> lvm

あとはこの結果を xargs などで配列にしてあげればいい

やり方はいくらでもあると思う。

takuya@:~$ ll /sbin/ | grep lvm | cut -d ' ' -f 13 | sort | uniq | xargs -I@ echo /sbin/@ |xargs echo | tr '  ' ' ,'
/sbin/lvchange,/sbin/lvconvert,/sbin/lvcreate,/sbin/lvdisplay,/sbin/lvextend,/sbin/lvmchange,/sbin/lvmconfig,/sbin/lvmdiskscan,/sbin/lvmsadc,/sbin/lvmsar,/sbin/lvreduce,/sbin/lvremove,/sbin/lvrename,/sbin/lvresize,/sbin/lvs,/sbin/lvscan,/sbin/pvchange,/sbin/pvck,/sbin/pvcreate,/sbin/pvdisplay,/sbin/pvmove,/sbin/pvremove,/sbin/pvresize,/sbin/pvs,/sbin/pvscan,/sbin/vgcfgbackup,/sbin/vgcfgrestore,/sbin/vgchange,/sbin/vgck,/sbin/vgconvert,/sbin/vgcreate,/sbin/vgdisplay,/sbin/vgexport,/sbin/vgextend,/sbin/vgimport,/sbin/vgimportclone,/sbin/vgmerge,/sbin/vgmknodes,/sbin/vgreduce,/sbin/vgremove,/sbin/vgrename,/sbin/vgs,/sbin/vgscan,/sbin/vgsplit

2019-09-27

このメモは随分前に書いていて、公開してなかったものなので、情報が古い可能性があります。昔LVMを触り始めたころに何故か sudo lvs が出来なくてこういうことをしました。今はできるはず。

sudoers のサンプル程度に使ってください。

暗号化ディスクのcrypt-unlock をSSH経由でして、ロック解除する

ディスクの暗号化をする

CPUにAES-NI の命令セットが載っているのに、ディスクを暗号化しないなんて、勿体無いとちょっと思ってるんです。

iPad / iPhoneiOS はもちろんのこと、Androidですらディスクは暗号化されているというのに、PCを使う我々は暗号化ディスクを使わずに平文で使うのはもったいない。

cpu がAESをサポートしているか調べる

takuya@:~$ cat /proc/cpuinfo | /bin/grep flags | head -n 1 | xargs -n1 echo | sort |  /bin/grep -i aes

AESがあるんですよね。IntelのCPUは安くてもAES付いてるので優秀だと思います。

暗号化ディスクの作成

Ubuntuのインストールなどで、ディスクの暗号かを選ぶと すべてのディスクは dm-crypt で暗号化される。

起動時にパスフレーズを入れる

dm-crypt で起動ディスクのパーティションを暗号化したら、

当然ですが、/ root の全てが暗号化されるので、パスフレーズを入れて解除しないと、起動ができません。

起動時にパスフレーズリモートssh 経由で入れる

通常のノートpcであれば問題ないのですが、遠隔からリモート再起動をしようとすると詰みますよね。

そこでSSH経由でパスフレーズを授受するする方法が一般的です。

linuxの起動は、いくつかのbootstrapに分かれているので

  • /boot
  • grub
  • initramfs
  • init

途中の initramfs のところで暗号化ディスクのロックを解除している。

通常はここでパスフレーズの入力になっている。

今回は、この場所にSSHを導入してリモートからロック解除を出来るようにする。

使うサーバーは簡易SSHサーバーのdropbearを使う。

インストール

apt-get install openssh-server dropbear busybox

dropbear をインストールしたら。dropbear-initramfs も一緒に導入された。

鍵の準備

鍵の場所は debian /ubuntu の場合は、最初から決まっていて

ここに公開鍵を入れる

/etc/dropbear-initramfs/authorized_keys

ここで入れた公開鍵が dropbearのSSHサーバー で使われるものになる。

私は無精をして、次のようにコピーして利用した。

sudo cp /root/.ssh/authorized_keys /etc/dropbear-initramfs/authorized_keys

initramfs の更新

authorized_keys が準備できたら、 iniramfs を作り変えて dropbear を入れた initramfs を作る

sudo update-initramfs -u

IPアドレスの指定

最後に、grub環境変数を設定して、initramfs に渡るようにします。

/etc/default/grub

GRUB_CMDLINE_LINUX="ip=192.168.2.99::192.168.2.1:255.255.255.0::eth0:none" 

このフォーマットは、決まっていて、次のように書いている。

ip=[dropbear_ip]::[gateway]:[netmask]::[nic]:none" 

grubの更新

最後にGrubの起動設定を書き換えて、dropbear に ip='' が渡るようにする。

update-grub

再起動してチェック

 ssh -o "HostKeyAlgorithms ssh-rsa" root@192.168.2.99

このときに、ユーザー名は root になる、IPは先程指定したIPアドレス秘密鍵は、authorized_keys で指定した公開鍵とペアになるものを使う。

ssh ログインできたら、ロック解除する

# crypt-unlock

ここでパスを入れれば、GUIからロック解除するのと同じ意味になる。

ちなみに、 Ctrl+Alt+F2 で切り替えたCLI(Xを使わない)モードでもcrypt-unlockが出来る。なので、手順が心配ならSSH経由にする前にcrypt-unlockを事前試してもいいと思う。

かんたんにロック解除は出来ますが、authorized_keys の入った initramfs は当然ですが暗号化されていません。ここもセキュリティを確保したいとなるとPXEブートなどで遠隔からgrub とinitram を導入するなどの手順を使うことになるんでしょうね。

実際にやってみた例

f:id:takuya_1st:20220107015233p:plain

参考資料

追記 2019-10-10

initramfs でdropbear を有効にしたら、NetworkManagerで、ネットワークデバイスが unmanaged になります。systemd が起動するより前に ネットワークデバイスが管理下に置かれるからみたいだけど。バグ?だよねこれ。

NetworkManagerが eth0(enp3s0)が 管理無しでどうやっても unmanaged になって、nmcli がmanaged にならないので、非常に苦しんだが。このdropbearが原因だった。

lvmでディスクを追加拡張するときに詰まった

pvcreate でディスクを追加しようとしたらエラーになった。

pvcreate /dev/sdb 

    ignoring or filtering 

なぜかエラーにメッセージが ignoring or filtering でディスクが追加できない

今回取った対策。

fdisk で適当なGPT/MBRパーティションにして、その後 pvcreate 無理やり上書きする。

LVMで作った20TB のディスクをext4 で扱えない。

ext4 が16TiB以上のディスクにならない。

ext4 は エクサバイトを扱えるはずなのですが、resize2fs をしようとしたら、エラーになりました。

なぜかというと 32bit で利用されているディスクフォーマットだったらしい。

そういえば、もうずいぶん長いこと拡張を繰り返して使っているLVMのext4 でした。

32bitのままだと、 16TiB以上の容量を扱えないんですね。困りました。ですが、大丈夫。変更できます。

ext4 を 64bit にする。

sudo umount /dev/mapper/data-my -a 
sudo e2fsck -fn /dev/mapper/data-my
## OKならyにする
## sudo e2fsck -fy /dev/mapper/data-my 
## 64bit にすると、16TiBをこえられる
resize2fs -b /dev/mapper/data-my # 12TBで10分ほど

resize2fs -b のコマンドで 32bit → 64bit にすることが出来る。事前に fsck が必要だった。

LVMの物理HDDを交換するときの手順

LVMでディスクを交換するときは最初にやるのはこれ

新しいディスクをLVMに接続し LVに割り当てる。
pvmove でディスク交換
vg から取り外し
物理的に取り出し

vgから古いディスクの取り外し( VG容量に余裕があるとき、容量を拡張するとき)

vg からディスクを外す前に pvmoveコマンドを先に実行する必要がある。

pvmove は物理ディスクにかきこまれたlvmが使っている領域をべつのlvm/ lv の割り当てディスクに移動させて、物理ディスクを安全に解放してくれる。

なんて便利な機能。

しかし、よくミスる。 「取り外しー>容量減らすー>ディスク減らす」と考えて、ついついvgreduce を打ってしまいまがち

pvmove /dev/sdX
vgreduce vg-name /dev/sdX
pvremove /dev/sdX
resize2fs /dev/mapper/vg-name-lvname

この順番が大事

ついつい vgreduce をやlvextend先にやろうとしてしまう。

pvmove は本当に便利なのにね。

容量の大きなディスクに入れ替えるとき( VG容量が満杯の余裕がないとき)

pvcreate /dev/sdX
vgextent  VGNAME /dev/sdX
pvmove /dev/sdY /dev/sdX
vgreduce VGNAME /dev/sdY
pvremove /dev/sdY
  1. 新しいディスクを pvcreate
  2. vg に新HDDを追加
  3. pvmove で旧HDD→新HDDへ
  4. vgreduce でVGの旧HDDを削減
  5. pvcremove で旧HDDを削除

こちらも順番が大事。

もし、pvmove をやめたいとき

pvmove 中に再起動が必要になったとか。pvmove 中に端末がおちちゃって経過がわからないとか、time コマンドをつけたかったとか。そういときに一旦中止する時にどうするのか。

pvmove --abort

これでpvmoveをキャンセルできます。

縮小するとき

LVMを必要以上に確保ししていて別のディスクに移したいとときは、

sudo mv /mnt/cryptDisk01/SOME_DATA /mnt/newDISK # 必要に応じ容量確保
sudo lvreduce -L -8T data/video --resizefs # 必要に応じて適当にLVを調整
sudo pvmove /dev/mapper/cryptDisk01
sudo vgreduce data /dev/mapper/cryptDisk01
sudo pvremove /dev/mapper/cryptDisk01
sudo lvextend -l 100%FREE  data/video
sudo resize2fs  /dev/mapper/data-video

適宜やれば確実に終わる。8TBは数日かかった・・・

2020-07-17

記述を変更

イオンカードのログインでワンタイムパスワードの送信画面をスキップする方法

イオンカードのログインにワンタイムパスワードの送信画面がめんどくさい

イオンカードにPCからログインすると、ワンタイムパスワードの送信画面になる。 f:id:takuya_1st:20190927013104p:plain

これは、リスクベース認証と呼ばれるものであり、リスクが高いアクセスは「追加認証」を要求するという考えによるものです

スマホページからログインすると追加認証がない。

不思議なんですが、「スマホページ」からアクセスすると「追加認証」が発生しません。

f:id:takuya_1st:20190927013402p:plain

スマホページにアクセスするには

Google 検索で、「イオンカード ログイン」 で検索してみてください。

Google検索はスマホページを優先的に表示します。そのためスマホページのログイン画面がまっさきに検索結果に上がってきます。

f:id:takuya_1st:20190927013646p:plain

Google検索からログインページに到達すると、パソコンでも追加認証が発生しません

これはセキュリティ対策をスルーしていますが犯罪ですか?

いいえ、イオンカードのセキュリティ対策が根本的に「誤り」です。

Google検索だけでたどり着くので、このようなアクセス方法は自然なものです。

イオングループが意図して隠しているわけでもありませんし、PCだけセキュリティを厳しくしていることは「明確に公開されていません」 つまり、私達が回避しても、不正アクセス禁止法にかかるようなものでもありません。

セキュリティに関して

このような、セキュリティ対策にならないものを、リスクベース認証と呼称し、間違った概念を広めているイオングループは意識を改めてもらいたいと思います。

スマホページにはメールによるワンタイムパスワードを導入せず、パソコンからのアクセスのみにワンタイムパスワードを導入して煩雑にしているだけです。煩雑にすることがセキュリティでは無いと思います。

また、このようなアクセス方法を不正アクセス禁止法にもとづく不正アクセスというためにはGoogle検索という誰でもたどり着く公開ページからのアクセスをストップする必要があり、対策していないイオンカード側の落ち度と言えます。

とっととスマホページにも2段階認証を導入するか、PCブラウザからの2段階認証を見直す必要があると思います。

なぜブログ記事にしたのか

このような現状はもう1年以上続いています。

最近、イオンカードが取った対策は、ログインページを使いにくくすることという「とんでもない」対策でした。

ダイアログをだして、ページ遷移を促すのですね。これはひどい対策です。

f:id:takuya_1st:20190927015546p:plain

iPadスマホですか?PCですか?よくわかりませんが、2段階認証を回避されたくないという意図をビンビンに感じます。

私は、これをみてもう記事にして公開したほうがいいなと思った次第です。

イオンカードのWEB明細必須化か・・・

さらに言えば、かりにアカウントを取られたとしてもカードの利用明細を閲覧には、経済的損害は発生しません。閲覧という行為に対するリスクベース認証として、現状は過剰すぎるのではないでしょうか。

登録情報の編集などリスクの高い変更についてリスクベース認証をするのは理解できますが、閲覧に二段階認証はやりすぎではないでしょうか。何度も書いてますが、「郵送」に比べてWEBページの閲覧は相当に煩雑であり、ユーザーに手間を押し付けるものであります。エコでもなんでもありません。郵便局の配達は、イオンカードの明細の有無に関係なくルートを巡っています。CO2削減にもなりません。ペーパー発行を控えてもエコにはなりません。コスト削減の言い訳に使うエコはエコロジーでなくエコノミーです。本当にエコロジーを実現したいのであれば配達先の集配局の近辺ででオンデマンド印刷して配達すればいいわけです。多大なコストを掛けたWEB明細を必須にするのは、利用率の改善の意図を疑ってしまいます。なぜ利用率が悪いのか、使い勝手が悪いのでは無いでしょうか。多大なコストを掛けて作ったWEB明細サービスやアプリが利用されないテコ入れであれば、「サンクコスト」としてとっとと諦めるか、ユーザー動線を調査をするのがあるべき姿だったと思われます。小手先の対応や必須化などと社内理論としか思えない言い訳につきあわされる私達利用者は溜まったもんじゃないですよね。

参考資料

利用端末の登録をしましたが、ログインするたびにワンタイムパスワードの送信画面が表示されます。 | よくあるご質問| 暮らしのマネーサイト

空白区切り文字列 を xargs で行へ展開-1行→複数行

xargs があるとすぐ出来ます。

xargs -n1  echo 

空白区切りされた文字列をぱぱっと複数行にする。 xargs と echo を組み合わせると楽。

takuya@~$ echo hello world hello world hello world hello world  | xargs -n1 echo
hello
world
hello
world
hello
world
hello
world

他の方法

他にも色々と方法があると思う。 for を使うとか、bash の展開をつかって配列にするとか。アレコレ考えられるけど、xargs を使うのがシェルっぽくていいと思う。

参考資料

https://qiita.com/maskedw/items/2dfdf6fa7eee991ddc45