CLOVER🍀

That was when it all began.

SSH経由でファイルシステムをマウントするSSHFSを、Ubuntu Linux 20.04 LTSで試す

これは、なにをしたくて書いたもの?

SSHFSという、SSHFUSE(Filesystem in Userspace)を使用したネットワークファイルシステムのマウントができる仕組みがあることを
知ったので、ちょっと試してみようかな、と。

SSHFS

SSHFSのリポジトリはこちら。

GitHub - libfuse/sshfs: A network filesystem client to connect to SSH servers

ArchLinuxにもドキュメントがあったり、

SSHFS - ArchWiki

他にも記事があったりします。

sshで他マシンのファイルシステムをマウントするには − @IT

SSHFSは、SFTPを使用してリモートファイルシステムをマウントできる仕組みです。

SSHFS allows you to mount a remote filesystem using SFTP.

SFTPは通常、SSHサーバーで利用できるので、サーバー側に特別な用意は不要です。

Most SSH servers support and enable this SFTP access by default, so SSHFS is very simple to use - there's nothing to do on the server-side.

SSHFS / About

ただ、開発状況については注意書きがありまして。

SSHFS / Development Status

SSHFS自体は多くのLinuxディストリビューションに使用可能で、すでにプロダクションで使用されているものの、SSHFS自体の開発が
あまりアクティブではないことが書かれています。
影響の大きい問題以外には、開発する余力はないそうです。

この点は押さえておいた方がよいでしょう。

また、裏の仕組みがSSHなので暗号化、ファイル転送のオーバーヘッドなどはかかることには注意が必要です。それでもよければ、
簡単に使えるので便利なのかな、と思います。

使い方はこちらに書かれており、sshfsコマンドでマウントして、fusermountコマンドでアンマウントする簡単なものです。

SSHFS / How to use

推奨としては、通常のユーザー(非root)で実行すること。

It is recommended to run SSHFS as regular user (not as root).

サーバー側のディレクトリを指定しない場合は、リモートのホームディレクトリをマウントする動作になるようです。

If the directory is omitted, SSHFS will mount the (remote) home directory.

アクセス方法は、パスワードを使うものでも、そうでなくても良さそうです。

If you need to enter a password sshfs will ask for it (actually it just runs ssh which asks for the password if needed).

今回は扱うつもりはありませんが、OSの起動時にマウントする方法についてはArchLinuxのWikiに記載があります。

archlinux / SSHFS / 自動マウント

では、1度試してみましょう。

環境

今回の環境は、こちら。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.4 LTS
Release:        20.04
Codename:       focal


$ uname -srvmpio
Linux 5.4.0-110-generic #124-Ubuntu SMP Thu Apr 14 19:46:19 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Ubuntu Linux 20.04 LTSを2つ用意します。片方はSSHサーバーとして使います。

SSHサーバー側のIPアドレスは、192.168.33.11とします。

SSHサーバー側

まずは、SSHサーバー側から用意していきます。

SSH接続用のユーザーを作成。

$ sudo adduser remote-user
$ su - remote-user

適当に、$HOMEディレクトリ配下にディレクトリを作って

$ mkdir dir1 dir2 dir3

ファイルも作ります。

$ echo hello > dir1/hello.txt
$ echo world > dir2/world.txt
$ echo ssh > dir3/ssh.txt

こんな感じになりました。

$ tree dir*
dir1
└── hello.txt
dir2
└── world.txt
dir3
└── ssh.txt

0 directories, 3 files

SSHFSを使って、リモートディレクトリをマウントする

では、SSHFSを使って、先ほど用意したリモートディレクトリをマウントしましょう。

まずはSSHFSをインストールします。

$ sudo apt install sshfs

今回インストールしたSSHFSのバージョン。

$ sshfs --version
SSHFS version 2.10.0
FUSE library version: 2.9.9
fusermount version: 2.9.9
using FUSE kernel interface version 7.19

マウント先のディレクトリを作成します。

$ mkdir sshfs-mnt

マウント。sshfs [接続ユーザー@]ホスト名:[マウントしたいディレクトリ] [マウントポイント]で行います。
少なくとも、ホスト名の指定は必要ですね(SFTPと同じです)。

$ sshfs remote-user@192.168.33.11: sshfs-mnt

今回は、ユーザー名とホスト名のみ指定しています。

今回はSSH公開鍵認証の設定をしなかったのでパスワードを聞かれますが、設定していればそのまま進みます。

remote-user@192.168.33.11's password:

マウントできました。

$ ls -l sshfs-mnt
合計 12
drwxrwxr-x 1 1001 1001 4096  5月 11 15:49 dir1
drwxrwxr-x 1 1001 1001 4096  5月 11 15:49 dir2
drwxrwxr-x 1 1001 1001 4096  5月 11 15:49 dir3

今回はマウントしたいディレクトリを指定しなかったので、リモートの$HOMEディレクトリをマウントしています。

$ ll mnt
合計 40
drwxr-xr-x 1    1001    1001 4096  5月 11 15:50 ./
drwxr-xr-x 5 xxxxx xxxxx 4096  5月 11 15:54 ../
-rw------- 1    1001    1001  182  5月 11 15:52 .bash_history
-rw-r--r-- 1    1001    1001  220  5月 11 15:47 .bash_logout
-rw-r--r-- 1    1001    1001 3771  5月 11 15:47 .bashrc
drwx------ 1    1001    1001 4096  5月 11 15:48 .cache/
-rw-r--r-- 1    1001    1001  807  5月 11 15:47 .profile
-rw-r--r-- 1    1001    1001    0  5月 11 15:50 .sudo_as_admin_successful
drwxrwxr-x 1    1001    1001 4096  5月 11 15:49 dir1/
drwxrwxr-x 1    1001    1001 4096  5月 11 15:49 dir2/
drwxrwxr-x 1    1001    1001 4096  5月 11 15:49 dir3/

ファイルの確認。

$ cat sshfs-mnt/dir1/hello.txt
hello

ディレクトリ内に移動して

$ cd sshfs-mnt/dir3

確認。

$ ll
合計 12
drwxrwxr-x 1 1001 1001 4096  5月 11 15:49 ./
drwxr-xr-x 1 1001 1001 4096  5月 11 15:50 ../
-rw-rw-r-- 1 1001 1001    4  5月 11 15:49 ssh.txt

ファイルを作成してみます。

$ echo sshfs > sshfs.txt

作成できました。

$ ls -l
合計 8
-rw-rw-r-- 1 1001 1001 4  5月 11 15:49 ssh.txt
-rw-rw-r-- 1 1001 1001 6  5月 11 15:56 sshfs.txt

このファイルはリモート側で書き換えたりもできます。

$ echo test > dir3/sshfs.txt

再度、マウントした側で見てみると反映されています。

$ cat sshfs.txt
test

つまり、SSHFSでマウントした時に指定したユーザーの権限で、マウントしたディレクトリ内で読み書きしていることになりますね。

マウントしたディレクトリから出て

$ cd ../..

アンマウント。アンマウントは、fusermountで行います。

$ fusermount -u sshfs-mnt

ところで、先ほどはこんな感じでマウントしましたが

$ sshfs remote-user@192.168.33.11: sshfs-mnt

末尾の:を忘れると、ちょっと不思議なエラーになります。

$ sshfs remote-user@192.168.33.11 sshfs-mnt
missing host
see `sshfs -h' for usage

接続時の指定は[user@]host:[dir]で、:までは必須です。

$ sshfs --help                                                                                                                                      
usage: sshfs [user@]host:[dir] mountpoint [options]

最初、見事に踏みました。

:の後ろにはディレクトリを指定できます。相対パスで書くと、リモートの$HOMEディレクトリからの相対パスになります。

$ sshfs remote-user@192.168.33.11:dir3 sshfs-mnt

上の例では、dir3ディレクトリをマウントしています。

$ ls -l sshfs-mnt
合計 8
-rw-rw-r-- 1 1001 1001 4  5月 11 15:49 ssh.txt
-rw-rw-r-- 1 1001 1001 5  5月 11 15:57 sshfs.txt

絶対パスで書いてもOKです。

$ sshfs remote-user@192.168.33.11:/home/remote-user/dir3 sshfs-mnt

オプションについてもいろいろありますが、今回はパス…。

$ sshfs --help
usage: sshfs [user@]host:[dir] mountpoint [options]

general options:
    -o opt,[opt...]        mount options
    -h   --help            print help
    -V   --version         print version

SSHFS options:
    -p PORT                equivalent to '-o port=PORT'
    -C                     equivalent to '-o compression=yes'
    -F ssh_configfile      specifies alternative ssh configuration file
    -1                     equivalent to '-o ssh_protocol=1'
    -o reconnect           reconnect to server
    -o delay_connect       delay connection to server
    -o sshfs_sync          synchronous writes
    -o no_readahead        synchronous reads (no speculative readahead)
    -o sync_readdir        synchronous readdir
    -o sshfs_debug         print some debugging information
    -o cache=BOOL          enable caching {yes,no} (default: yes)
    -o cache_max_size=N    sets the maximum size of the cache (default: 10000)
    -o cache_timeout=N     sets timeout for caches in seconds (default: 20)
    -o cache_X_timeout=N   sets timeout for {stat,dir,link} cache
    -o cache_clean_interval=N
                           sets the interval for automatic cleaning of the
                           cache (default: 60)
    -o cache_min_clean_interval=N
                           sets the interval for forced cleaning of the
                           cache if full (default: 5)
    -o workaround=LIST     colon separated list of workarounds
             none             no workarounds enabled
             [no]rename       fix renaming to existing file (default: off)
             [no]truncate     fix truncate for old servers (default: off)
             [no]buflimit     fix buffer fillup bug in server (default: on)
             [no]fstat        fix fstat for old servers (default: off)
    -o idmap=TYPE          user/group ID mapping (default: none)
             none             no translation of the ID space
             user             only translate UID/GID of connecting user
             file             translate UIDs/GIDs contained in uidfile/gidfile
    -o uidfile=FILE        file containing username:remote_uid mappings
    -o gidfile=FILE        file containing groupname:remote_gid mappings
    -o nomap=TYPE          with idmap=file, how to handle missing mappings
             ignore           don't do any re-mapping
             error            return an error (default)
    -o ssh_command=CMD     execute CMD instead of 'ssh'
    -o ssh_protocol=N      ssh protocol to use (default: 2)
    -o sftp_server=SERV    path to sftp server or subsystem (default: sftp)
    -o directport=PORT     directly connect to PORT bypassing ssh
    -o slave               communicate over stdin and stdout bypassing network
    -o disable_hardlink    link(2) will return with errno set to ENOSYS
    -o transform_symlinks  transform absolute symlinks to relative
    -o follow_symlinks     follow symlinks on the server
    -o no_check_root       don't check for existence of 'dir' on server
    -o password_stdin      read password from stdin (only for pam_mount!)
    -o SSHOPT=VAL          ssh options (see man ssh_config)

FUSE options:
    -d   -o debug          enable debug output (implies -f)
    -f                     foreground operation
    -s                     disable multi-threaded operation

    -o allow_other         allow access to other users
    -o allow_root          allow access to root
    -o auto_unmount        auto unmount on process termination
    -o nonempty            allow mounts over non-empty file/dir
    -o default_permissions enable permission checking by kernel
    -o fsname=NAME         set filesystem name
    -o subtype=NAME        set filesystem type
    -o large_read          issue large read requests (2.4 only)
    -o max_read=N          set maximum size of read requests

    -o hard_remove         immediate removal (don't hide files)
    -o use_ino             let filesystem set inode numbers
    -o readdir_ino         try to fill in d_ino in readdir
    -o direct_io           use direct I/O
    -o kernel_cache        cache files in kernel
    -o [no]auto_cache      enable caching based on modification times (off)
    -o umask=M             set file permissions (octal)
    -o uid=N               set file owner
    -o gid=N               set file group
    -o entry_timeout=T     cache timeout for names (1.0s)
    -o negative_timeout=T  cache timeout for deleted names (0.0s)
    -o attr_timeout=T      cache timeout for attributes (1.0s)
    -o ac_attr_timeout=T   auto cache timeout for attributes (attr_timeout)
    -o noforget            never forget cached inodes
    -o remember=T          remember cached inodes for T seconds (0s)
    -o nopath              don't supply path if not necessary
    -o intr                allow requests to be interrupted
    -o intr_signal=NUM     signal to send on interrupt (10)
    -o modules=M1[:M2...]  names of modules to push onto filesystem stack

    -o max_write=N         set maximum size of write requests
    -o max_readahead=N     set maximum readahead
    -o max_background=N    set number of maximum background requests
    -o congestion_threshold=N  set kernel's congestion threshold
    -o async_read          perform reads asynchronously (default)
    -o sync_read           perform reads synchronously
    -o atomic_o_trunc      enable atomic open+truncate support
    -o big_writes          enable larger than 4kB writes
    -o no_remote_lock      disable remote file locking
    -o no_remote_flock     disable remote file locking (BSD)
    -o no_remote_posix_lock disable remove file locking (POSIX)
    -o [no_]splice_write   use splice to write to the fuse device
    -o [no_]splice_move    move data while splicing to the fuse device
    -o [no_]splice_read    use splice to read from the fuse device

Module options:

[iconv]
    -o from_code=CHARSET   original encoding of file names (default: UTF-8)
    -o to_code=CHARSET      new encoding of the file names (default: UTF-8)

[subdir]
    -o subdir=DIR           prepend this directory to all paths (mandatory)
    -o [no]rellinks         transform absolute symlinks to relative

今回はここまでにしておきますが、先にも書きましたがOS起動時にマウントしたい場合はこちら。

archlinux / SSHFS / 自動マウント

まとめ

SSHFSを試してみました。

割と簡単に使えるのと、用意の敷居も低くて良いですね。
ちょっとしたリモートファイルシステムとして、簡単に利用する分には知っておくと便利なのかな、と思います。

Ubuntu Linux 20.04 LTSでホスト名を(永続的に)変更したい

これは、なにをしたくて書いたもの?

Linuxのホスト名の変え方を、ちゃんと見てきていなかったので、この機会にちょっと見ておきたいな、と。

hostnamectlnmcli general hostnameのどちらかを使って変更するのが良いみたいですね。

環境

環境は、Ubuntu Linux 20.04 LTSを使って行います。Vagrantの以下のBoxを使用しました。Libvirt Providerです。

generic/ubuntu2004

確認時点での情報。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.4 LTS
Release:        20.04
Codename:       focal


$ uname -srvmpio
Linux 5.4.0-110-generic #124-Ubuntu SMP Thu Apr 14 19:46:19 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

hostnameコマンドや直接/etc/hostnameファイルを修正して変更した場合

まずは、hostnameコマンド。

hostname(1) - Linux manual page

現在のホスト名。

$ hostname
ubuntu2004.localdomain

変更してみます。

$ sudo hostname myhost

変わりました。

$ hostname
myhost

ただ、この方法で変更してもOSを再起動すると

$ sudo reboot

元に戻ってしまいます。

$ hostname
ubuntu2004.localdomain

次に、/etc/hostnameファイルを変更してみます。

$ sudo vim /etc/hostname

このように。

/etc/hostname

myhost

この変更は、すぐには反映されません。

$ hostname
ubuntu2004.localdomain

OSを再起動すると

$ sudo reboot

反映されます。

$ hostname
myhost

hostnameの説明を見るとわかるのですが、起動時に1度読むだけだからですね。

The host name is usually set once at system startup by reading the contents of a file which contains the host name, e.g. /etc/hostname).

hostname(1) - Linux manual page

/etc/hostnameファイルは元に戻して(再起動もして)おきます。

/etc/hostname

ubuntu2004.localdomain

hostnamectlコマンドで変更する

次に、hostnamectlコマンドを見てみましょう。

hostnamectl(1) - Linux manual page

Ubuntu Manpage: hostnamectl - Control the system hostname

現時点でのホスト名。

$ hostname
ubuntu2004.localdomain

hostnamectlコマンドで見ると、もっと情報が表示されます。

$ hostnamectl
   Static hostname: ubuntu2004.localdomain
         Icon name: computer-vm
           Chassis: vm
        Machine ID: e7950de6a4f749c3a0427899e320e4c0
           Boot ID: 0da5d3ff14ef4bf487b70c800a73eb8b
    Virtualization: kvm
  Operating System: Ubuntu 20.04.4 LTS
            Kernel: Linux 5.4.0-110-generic
      Architecture: x86-64

ホスト名の変更は、root権限でhostnamectl set-hostnameを実行。

$ sudo hostnamectl set-hostname myhost

こちらの場合、即座に反映されます。

$ hostname
myhost

/etc/hostnameファイルも変更されます。

/etc/hostname

myhost

OSを再起動しても

$ sudo reboot

変更は反映されたままです。

$ hostname
myhost

ところで、hostnamectl set-hostnameでオプションを指定した場合は、指定したホスト名だけが変更されることが書かれています。

however, if one or more of --static, --transient, --pretty are used, only the selected hostnames are changed.

Ubuntu Manpage: hostnamectl - Control the system hostname

3つありますね。違いは?

This tool distinguishes three different hostnames

staticは起動時にカーネルが初期化しているもの。

the static hostname which is used to initialize the kernel hostname at boot (e.g. "lennarts-laptop"),

transientはネットワーク設定のフォールバック値で、staticにあたるホスト名が設定され、それが妥当であればそちらが使用されtransient
ホスト名は使われないみたいです。

transient hostname which is a fallback value received from network configuration. If a static hostname is set, and is valid (something other than localhost), then the transient hostname is not used.

prettyはハイレベルなホスト名だということですが…今回は気にしないことにします…。

the high-level "pretty" hostname which might include all kinds of special characters (e.g. "Lennart's Laptop")

それぞれの情報を見てみましょう。

$ hostnamectl
   Static hostname: myhost
         Icon name: computer-vm
           Chassis: vm
        Machine ID: e7950de6a4f749c3a0427899e320e4c0
           Boot ID: 769e58a6b4d941459ccfae7795de713f
    Virtualization: kvm
  Operating System: Ubuntu 20.04.4 LTS
            Kernel: Linux 5.4.0-110-generic
      Architecture: x86-64


$ hostnamectl --static 
myhost


$ hostnamectl --transient 
myhost


$ hostnamectl --pretty


$ hostname
myhost

prettyは設定されていなさそうです。

試しに、--transientを指定してみます。

$ sudo hostnamectl set-hostname --transient myhost2

結果。Transient hostnameが増えたりしていますが、hostnameは変わりませんね。

$ hostnamectl
   Static hostname: myhost
Transient hostname: myhost2
         Icon name: computer-vm
           Chassis: vm
        Machine ID: e7950de6a4f749c3a0427899e320e4c0
           Boot ID: 769e58a6b4d941459ccfae7795de713f
    Virtualization: kvm
  Operating System: Ubuntu 20.04.4 LTS
            Kernel: Linux 5.4.0-110-generic
      Architecture: x86-64


$ hostnamectl --static
myhost


$ hostnamectl --transient
myhost2


$ hostnamectl --pretty


$ hostname
myhost

再起動すると

$ sudo reboot

Transient hostnameはいなくなりました。

$ hostnamectl
   Static hostname: myhost
         Icon name: computer-vm
           Chassis: vm
        Machine ID: e7950de6a4f749c3a0427899e320e4c0
           Boot ID: f54e564b8fe94ddc9e1e5d30eeaa1a65
    Virtualization: kvm
  Operating System: Ubuntu 20.04.4 LTS
            Kernel: Linux 5.4.0-110-generic
      Architecture: x86-64

nmcli general hostnameを使う

最後はNetworkManagerのnmcliを使います。

この環境ではNetworkManagerがインストールされていなかったので、まずはインストールから…。

$ sudo apt install network-manager

使用するのは、nmcli generalコマンドです。

nmcli general

説明。

$ nmcli general hostname -h
使い方: nmcli general hostname { 引数 | help }

引数 := [<ホスト名>]

システムの永続的なホスト名を取得または変更します。
引数を付けずに実行すると、現在設定されているホスト名を出力します。ホスト名を
渡すと、そのホスト名をシステムの永続的なホスト名として新たに設定します。

永続的なホスト名の表示または設定を行うようです。

現在の値を表示。

$ nmcli general hostname
ubuntu2004.localdomain

変更。root権限が必要です。

$ sudo nmcli general hostname myhost

確認。

各種コマンドの結果。

$ hostnamectl
   Static hostname: myhost
         Icon name: computer-vm
           Chassis: vm
        Machine ID: e7950de6a4f749c3a0427899e320e4c0
           Boot ID: bc2fc058a7b6409e91ff3f13be0b553d
    Virtualization: kvm
  Operating System: Ubuntu 20.04.4 LTS
            Kernel: Linux 5.4.0-110-generic
      Architecture: x86-64


$ hostname
myhost

/etc/hostnameファイル。

/etc/hostname

myhost

OS再起動後の確認は省略します。

また、generalhostnameの部分はそれぞれghに省略することができます。

$ nmcli g h
ubuntu2004.localdomain

変更。

$ sudo nmcli g h myhost

確認。

$ nmcli g h
myhost


$ hostname
myhost


$ hostnamectl
   Static hostname: myhost
         Icon name: computer-vm
           Chassis: vm
        Machine ID: e7950de6a4f749c3a0427899e320e4c0
           Boot ID: 7ff8e9b79d854d17b67e470fb8d37e69
    Virtualization: kvm
  Operating System: Ubuntu 20.04.4 LTS
            Kernel: Linux 5.4.0-110-generic
      Architecture: x86-64

まとめ

Ubuntu Linux 20.04 LTSを使ってですが、ホスト名の変更方法を見てみました。

hostnamectlまたはNetworkManagerを使えば良さそうですが、使える環境ならNetworkManagerを利用すればいいのではないでしょうか。