Macのssh-agent

Macssh-agentキーチェーンとの連携ができるので、上手く使いこなすと便利そうですが、仕組みがあまりよく分からないで使うのも気持ち悪かったので整理してみました。

はじめに

1. ssh-agentについて

  • OpenSSH の認証エージェント
  • macOS はLeopard から標準インストールされている
  • SSH の公開鍵認証で使う秘密鍵をssh-agent に登録すると、サーバにSSH で接続する際のパスフレーズの手入力を省略できる(ssh-agent が代理でパスコードを入力してくれる)
  • OS をシステム終了するとssh-agent の登録情報が削除されるので、OS を起動する度に再登録が必要

2. キーチェーンの役割について

  • SSH の公開鍵認証で使う秘密鍵のパスコードをキーチェーンに登録すると、登録した秘密鍵をパスコード付きでssh-agent に読み込むことができる
  • キーチェーンには秘密鍵のパスフレーズが保存される(秘密鍵自体は保存されないので、キーチェーンから秘密鍵の復元はできない)

環境について

クライアント側の環境

  • macOS Monterey

サーバ側の環境

  • Ubuntu 20.04.4 LTS

準備

1. SSHの公開鍵認証で使う鍵の作成

今回、鍵の形式はEd25519 で作成します。
作成する際にパスフレーズの入力を求められるので、任意の文字列を指定します。

ssh-keygen -t ed25519
→ パスフレーズを入力する
ls -l ~/.ssh/
→ ~/.ssh/に秘密鍵「id_ed25519」と公開鍵「id_ed25519.pub」が格納されている
  • id_ed25519
    • クライアント側で署名に使う秘密鍵
  • id_ed25519.pub
    • サーバ側で検証に使う公開鍵

2. 接続先のサーバに公開鍵を登録

下記のコマンドで指定したサーバ・ユーザの ~/.ssh/authorized_keys に公開鍵を登録します。

ssh-copy-id -i ~/.ssh/id_ed25519.pub [email protected]

※ サーバ「test.example」の「/home/ubuntu/.ssh/authorized_keys」に登録されます

3. 接続確認

SSH の公開鍵認証でサーバに接続できるか確認します。

ssh -i ~/.ssh/id_ed25519 [email protected]
→ パスフレーズを入力して接続に成功
exit

ちなみに、オプション-i で秘密鍵を指定しなくても同じ様に接続できました。

ここまでは、ssh-agent を使わないSSH の公開鍵認証です。

ssh-agentを使う

ssh-agent に秘密鍵を登録してSSH の公開鍵認証でサーバに接続します。

1. 秘密鍵をssh-agentに登録

ssh-add ~/.ssh/id_ed25519
→ パスフレーズを入力して登録する

ちなみに、秘密鍵を指定しなくても同じ様に登録できました。
その場合、~/.ssh/ に複数の秘密鍵のファイルがあると、全ての秘密鍵のパスフレーズの入力を求められ登録しようとします。

2. 秘密鍵がssh-agentに登録されていることを確認

ssh-add -l
→ 登録されている秘密鍵に対応する公開鍵のフィンガープリントが表示される

3. 接続確認

パスフレーズを入力しないでサーバに接続できるか確認します。

ssh -i ~/.ssh/id_ed25519 [email protected]
→ パスフレーズの入力を求められずに接続に成功
exit

パスフレーズを入力しないで接続できたということは、ssh-agent が代理でパスフレーズを入力してくれたということになります。

続けて、オプション-i で秘密鍵を指定しないで接続できるか確認します。

ssh [email protected]
→ パスフレーズの入力を求められずに接続に成功
exit

こちらも同じ様にパスフレーズを入力しないで接続できました。

以降、パソコンのシステムを終了するまでパスフレーズの入力が求められなくなるので、便利ではありますがパスフレーズを知らない第三者もこのコマンドを入力するだけでサーバにSSH 接続できてしまうので、離席する際はパソコンをロックする等の運用上の配慮が必要になります。

キーチェーンを使う

秘密鍵のパスフレーズをキーチェーンに登録し、登録したキーチェーンのパスフレーズをssh-agent に読み込んでSSH の公開鍵認証でサーバに接続します。

1. 秘密鍵のパスフレーズをキーチェーンに登録

ssh-add --apple-use-keychain ~/.ssh/id_ed25519
→ パスフレーズを入力して登録する
  • オプション-K非推奨となり、替わりに–apple-use-keychain が用意されていました
  • 引数の秘密鍵の指定を省略すると、~/.ssh/ に格納されている全ての秘密鍵の登録を試みます(各鍵のパスフレーズを聞かれるので、入力して正しければ登録されます)
  • 上記のコマンドを実行すると、ssh-agent にも秘密鍵が登録されました

2. キーチェーンに登録されていることを確認

キーチェーンアクセスで秘密鍵のパスフレーズがキーチェーンに登録されていることを確認します。

キーチェーンアクセスを開き、右上の検索窓に”SSH” と入力して一覧の表示を絞り込むと、登録した秘密鍵が表示されます。

キーチェーンアクセス(一覧)
キーチェーンアクセス(一覧)

一覧の秘密鍵の行をクリックして詳細画面を開き、[パスワードを表示] のチェックをONにすると秘密鍵のパスフレーズが表示されます。

キーチェーンアクセス(詳細)
キーチェーンアクセス(詳細)

3. ssh-agentに登録されている秘密鍵を削除

キーチェーンの秘密鍵をssh-agent に読み込むので、前述「1. 秘密鍵をssh-agentに登録」でssh-agent に登録した秘密鍵を一旦削除します。

ssh-add -D

4. キーチェーンの秘密鍵をssh-agentに読み込む

ssh-add --apple-load-keychain ~/.ssh/id_ed25519
  • オプション-A非推奨となり、替わりに–apple-load-keychain が用意されていました
  • 引数の秘密鍵の指定を省略すると、キーチェーンの全ての秘密鍵がssh-agent に読み込まれます(パスフレーズの入力が求められずに読み込まれます)

5. 秘密鍵がssh-agentに登録されていることを確認

ssh-add -l
→ 登録されている秘密鍵に対応する公開鍵のフィンガープリントが表示される

6. 接続確認

パスフレーズを入力しないでサーバに接続できるか確認します。

ssh [email protected]
→ パスフレーズの入力を求められずに接続に成功
exit

設定

~/.ssh/config

任意でssh-agent に関係する下記のオプションを指定することができます。

Host *
 AddKeysToAgent yes
 UseKeyChain yes
  • AddKeysToAgent
    • サーバにSSHで接続した際に、秘密鍵をssh-agentに登録する設定
    • yes:登録する、no:登録しない(デフォルト)、他にconfirmとaskが指定できる
    • yesにすると、ssh-add を実行する必要がなくなる
  • UseKeyChain
    • サーバにSSHで接続した際に、秘密鍵をキーチェーンに登録する設定
    • yes:登録する、no:登録しない(デフォルト)
    • yesにすると、ssh-add –apple-use-keychain を実行する必要がなくなる

どう使うか

秘密鍵のパスフレーズをキーチェーンで管理して使う

以下の手順でssh-agent を使う

  1. 公開鍵認証で使う鍵を作ったタイミングで秘密鍵をキーチェーンに登録する
    • ssh-add –apple-use-keychain ~/.ssh/id_ed25519パスコードを入力
  2. SSH でサーバに接続する前にキーチェーンの秘密鍵をssh-agent に登録する
    • ssh-add –apple-load-keychain
  3. SSH でサーバに接続する

OS を起動する度に2.を実行する必要がありますが、普段はパスコードの手入力が必要なくなるというのが利点としてあります。
非推奨になったオプション-A に比べると–apple-load-keychain が覚えづらいのが残念な感じです。
この使い方であれば、config の設定は必要なさそうです。

秘密鍵のパスフレーズをキーチェーンで管理しないで使う(configの設定なし)

以下の手順でssh-agent を使う

  1. SSH でサーバに接続する前に秘密鍵をssh-agent に登録する
    • ssh-addパスコードを入力
  2. SSHでサーバに接続する

OS を起動する度にパスコードの手入力が必要なので、パスコードの運用が雑になりそうです。
普段からssh-add コマンドを使うのでssh-agent を意識するシンプルな使い方という感じです。

秘密鍵のパスフレーズをキーチェーンで管理しないで使う(configの設定あり)

以下の手順でssh-agent を使う

  1. config にSSH 接続の際に秘密鍵をssh-agent に登録する設定をする
    • AddKeysToAgent yes
  2. SSH でサーバに接続する(OS 起動後の初回)
  3. SSH でサーバに接続する(2回目以降)

OS を起動する度にパスコードの入力が必要なので、パスコードの運用が雑になりそうです。
普段は ssh コマンドだけを使えばよくなるので、ssh-agent を意識しなくなりそうです。

あとがき

Macssh-agentについて整理できたようで整理できていない感じですが、どう使うかの選択肢は整理できたと思います。
最後に感想とメモのようなものを書き残しておきます。

  • ssh-add のキーチェーンを扱うオプションについて
    • macOS Monterey で-K と-A が非推奨になったらしい
    • 新しい–apple-use-keychain と–apple-load-keychain 覚えづらい
  • config のUseKeyChain について
    • 秘密鍵は基本的に意識して扱いたいので、無意識で永続的に保存される仕組みは使いたくない(sshコマンドの実行でキーチェーンに登録したくない)
  • キーチェーンに登録するのは秘密鍵の保存場所とパスコードの情報
    • ~/.ssh/ の秘密鍵を削除するとキーチェーンに登録されている情報はゴミになる
    • キーチェーンから秘密鍵を復元できない
  • ssh-agent を使わないという選択
    • 離席する際のパソコンのロックが徹底できないのであれば使わない方がよい
    • ssh-agent はあくまでも利便性を向上させるツールなので無理して使うことはない
  • 秘密鍵のパスコードを絶対第三者に使われたくない
    • パスコードをキーチェーンで管理すれば、ウェブサイト向けのパスワードマネージャー(1Passwordなど)のような感覚でパスコードをセキュアに扱うことができる
  • ssh-agent のプロセス起動
    • OS を起動した状態ではssh-agent が起動していない
    • ssh コマンドやssh-add コマンドを実行するとssh-agent が起動する(ps aux | grep ssh-agent で確認)
  • シェル起動時にssh-agent に登録する
    • キーチェーンに登録して、~/.zshrc にssh-add –apple-load-keychain を記述する
    • ssh コマンドでパスフレーズの入力を求められずに接続できる
    • 普段ssh-agent とパスフレーズを全く意識する必要がなくなり利便性はmax

参考

UbuntuにGitLabをインストール

UbuntuGitLab をインストールします。
筐体はRaspberry Pi で、Ubuntu をインストール直後の状態にインストールします。

環境について

  • Raspberry Pi 4 Model B / 8GB
  • Ubuntu Server 20.04.4 LTS (64bit)

ハードウェア要件

  • ストレージ(空き容量2.5 GB)
  • CPU(推奨4コア、500ユーザー)
  • メモリー(4GB RAM、500ユーザー)

今回使うRaspberry Pi は、CPU は最小要件をぎりぎり満たしていました。

準備

Raspberry Pi はUbuntu をインストールしてパソコンからSSH接続できることを確認していました。
GitLab をインストールする前に下記の作業をしておきます。

1. パッケージを最新に更新

sudo apt update
sudo apt upgrade

2. ストレージの空き領域の確認

pwd
→ /home/ubuntu
df -h ./
→ Filesystem      Size  Used Avail Use% Mounted on
   /dev/mmcblk0p2   30G  2.8G   26G  10% /

インストール

GitLabのコミュニティサイトに推奨のインストール方法として、オールインワンパッケージのインストール手順が記載されていたので、こちらを参考にGitLab のインストール作業を進めます。

オールインワンパッケージ(推奨のインストール方法)

1. 依存パッケージのインストールと設定(必須)

1行目のパッケージのアップデートは準備作業で完了しているので不要。
2行目のライブラリのインストールは、既にSSH接続できているのでOpen SSHサーバは不要ですが、実行しても失敗するだけなのでこのまま実行します。

sudo apt-get update
sudo apt-get install -y curl openssh-server ca-certificates

2. 依存パッケージのインストールと設定(任意)

メールの送信に使うPostfix をインストールします。
外部のSMTPサーバーを使う場合は不要です。

sudo apt-get install -y postfix
→ 設定画面が表示
   "Internet Site" を選択
   "mail name" に外部DNS名 ※今回「a.example」を入力

3. GitLabパッケージのリポジトリへの追加

curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh | sudo bash

4. GitLabのインストール

EXTERNAL_URL に自分のサーバのURLを指定します。
イントラでHTTPSにしないので、スキーム部はhttpにします。(気が向いたら後でHTTPにします)

sudo EXTERNAL_URL="http://gitlab.a.example" apt-get install gitlab-ee

インストールが完了すると、下記のメッセージが表示されました。

インストール完了

パスワードのリセットを強く推奨と書かれています。

設定のオプションを理解したければ、Omnibus GitLab readme を読めと書かれています。

5. ストレージの空き領域の確認

GitLab をインストール後の容量を確認します。
Used がインストールする前は2.8G だったので、約3.8G 増えています。
ハードウェア要件は空き容量2.5 GB でしたが、1.3G 程余分に使われたようです。
空き容量は22G と潤沢ではないですが、とりあえずはこれでよしとします。

df -h ./
→ Filesystem      Size  Used Avail Use% Mounted on
   /dev/mmcblk0p2   30G  6.6G   22G  24% /

6. rootユーザのパスワードの確認

/etc/gitlab/initial_root_password というファイルにroot ユーザのパスワードが保存されているので確認します。
このファイルは24時間後に自動削除されるようです。

sudo cat /etc/gitlab/initial_root_password
→ Password: <パスワード>

7. ブラウザでGitLab にログイン

インストール完了時に「http://gitlab.a.example」でGitLab が使えるというメッセージがありましたが、LAN環境のサーバでDNSの登録をしていないので、サーバのIPアドレスを指定した下記のURLにアクセスすると、ログインページが表示されました。

  • http://<サーバのIPアドレス>/gitlab/
ログインページ

ドメイン名でアクセスできるようにするために、パソコンのhosts ファイルにサーバの行を追加します。
※ パソコンはMacなので、/etc/hosts を更新します。

sudo vi /etc/hosts
→追加した行
  <サーバのIPアドレス>   gitlab.a.example

下記のURLにアクセスすると、ログインページが表示されました。

  • http://gitlab.a.example
ログインページ

ユーザ名root と先ほど確認したパスワードを入力するとログインに成功しました。

ログイン成功

8. GitLabのバージョンの確認

右上の?アイコンの[Help] をクリックして表示されるページでバージョンを確認すると、14.9.3-ee となっていました。

GitLab Enterprise Edition 14.9.3-ee

OSS版のCE でよかったのですが、公式サイトに推奨は有料版のEEで、ライセンス登録しななくてもCE と同じ機能が使えるとのことだったので、これでよいことにします。

9. rootユーザのパスワード変更

右上のアイコンの[Edit profile] をクリックし、左の縦長のメニューにある南京錠のアイコンをクリックして表示されるページでパスワードを変更します。

インストール直後の状態の確認

1. バンドルインストールされたライブラリの確認

cat /opt/gitlab/version-manifest.txt

大量に表示されたのでここに貼り付けませんが、ぱっと見では下記のページに掲載されている内容と一致していました。

2. 設定ファイルの確認

GitLab の設定ファイル/etc/gitlab/gitlab.rb のコメントアウトされていない行だけを抽出して確認します。(2つ目のgrepで空白行を除去)

sudo grep -v "^#" /etc/gitlab/gitlab.rb | grep -v "^$"
→ external_url 'http://gitlab.a.example'

インストール時に指定したEXTERNAL_URL=”http://gitlab.a.example” がここにセットされていました。
他は全てコメントアウトされていました。

3. サービスの状態を確認

sudo gitlab-ctl status

ちなみに、サービスの起動・停止・再起動は下記のコマンドで実行します。

sudo gitlab-ctl start
sudo gitlab-ctl stop
sudo gitlab-ctl restart

あとがき

ひとまず、インストールして正常に動作していることの確認ができました。最低限の使える状態にはなったようです。
インストール後の推奨される次のステップというのがあるので、まずはこちらを確認して必要なことがあれば対応しようと思います。

参照

Raspberry Pi Imager v1.7.2

Raspberry Pi OS や他のOSをmicroSDカードに書き込んで簡単にインストールすることができるツールRaspberry Pi Imager の使用手順を解説します。

環境について

  • macOS Monterey
  • Raspberry Pi Imager (v1.7.2)

Raspberry Pi Imager はmacOS以外に、Windows、Ubuntu(x86)、Raspberry Pi OS にもインストールできるようです。

インストール

Raspberry Pi の公式サイトからRaspberry Pi Imager のイメージファイルをダウンロードしてインストールすることができます。

Homebrew を使ってインストール

今回は、Homebrew にパッケージがあったので、Homebrew を使ってインストールしました。

ターミナルで下記のコマンドを実行してインストールします。

brew install --cask raspberry-pi-imager

使い方

1. Raspberry Pi Imager の初回起動

Raspberry Pi Imager を起動します。

Raspberry Pi Imager メニュー

2. OSを選ぶ

[OSを選ぶ] ボタンをクリックします。

OSを選択(カテゴリー)

一番上のRaspberry Pi OS に続けて、2行目以降はOSのカテゴリーが表示されます。
今回はUbuntu Server (64bit) をインストールするので、ここではOther general-purpose OS を選択します。

OSを選択(Other general-purpose OS)

続けて、Ubuntu を選択します。

OSを選択(Ubuntu)

Ubuntu の種類がいくつか表示されるので、今回はこの中からUbuntu Server 20.04.4 LTS (RPi 3/4/400) 64-bit server OS with long-term support for arm64 architectures を選択しました。

3. ストレージを選ぶ

パソコンのSDカードスロットにmicroSDカード を挿入してOSに認識されていることを確認した上で、[ストレージを選ぶ] ボタンをクリックします。

ストレージを選択

挿入したmicroSDカード のストレージが表示されているので選択します。

4. 詳細な設定

OS を選択した際に右下に表示される歯車ボタンをクリックします。

Raspberry Pi Imager メニュー(選択後)

歯車ボタンをクリックすると、Wifiのパスワードをキーチェーンから読み込んで設定するかを確認するウィンドウが表示されました。
macOS ではWi-Fiのアクセスポイントのパスワードはキーチェーンに保存されているので、手入力ではなくキーチェーンから読み込んで自動入力してくれるようです。

詳細設定(キーチェーンから読み取り)

普通に便利そうだったので、今回は[Yes] をクリックしました。

詳細設定(設定項目)

詳細な設定 のウィンドウが表示されます。
上のイメージは縦長ですが、実際は横長のウィンドウで縦にスクロールします。どのような入力項目があるかを見やすくしたかったので、4つのスクリーンショットをくっつけて1つのイメージにしました。

Wi-Fiを設定する にキーチェーンに保存されていたWi-Fiのアクセスポイントとパスワードが自動入力されていました。

4. 詳細な設定 ※今回個人的にやった設定

カスタマイズオプション:いつも使う設定にする

  • ホスト名:OFF
  • SSHを有効化する:ON
    • パスワード認証を使う
  • ユーザー名とパスワードを設定する:ON
    • ユーザー名:任意
    • パスワード:任意
  • Wi-Fiを設定する:ON
    • SSID:任意
    • ステルスSSID:OFF
    • パスワード:任意
    • Wifiを使う国:JP
  • ロケール設定をする:ON
    • タイムゾーン:Asia/Tokyo
    • キーボードレイアウト:jp

永続的な設定

  • 終わったときに音を鳴らす:ON
  • 終わったときにメディアを取り出す:ON
  • テレメトリーを有効化する:OFF

5. microSDカードに書き込む

[書き込む] ボタンをクリックします。

Raspberry Pi Imager メニュー(選択後)

[書き込む] ボタンをクリックすると、処理を続行するかの確認メッセージが表示されました。

書き込む(確認)

[はい] ボタンをクリックします。

プログレスバーが表示され、書き込みが完了すると、完了メッセージが表示されました。
※ 時計で測り忘れたけれど、5分くらいで書き込みできました

書き込む(完了)

microSDカードに書き込んだOSの起動と確認

1. OSの初回起動とSSHの接続確認

手元のRaspberry Pi 4 にmicroSDカードを差し込み電源を入れます。

Wi-Fiのルータの管理画面を開き、ルータがRaspberry Pi 4 のOSを認識して、DHCPでIPアドレスを割り当てたことを確認します。

詳細な設定 でSSHを有効化していたので、ターミナルで下記のコマンドを実行してSSH接続します。

ssh <設定したユーザー名>@<DHCPで割り当てられたIPアドレス>

パスワードの入力を求められるので、設定したパスワードを入力すると接続に成功しました。

2. 各種設定の確認

ネットワーク(Wi-Fi)

cat /etc/netplan/50-cloud-init.yaml
↓
network:
    version: 2
    wifis:
        renderer: networkd
        wlan0:
            access-points:
                <アクセスポイントのSSID>:
                    password: <パスワード(64文字)>
            dhcp4: true
            optional: true

パスワードには、wpa_passphrase を使って生成されるPSKと同じ64文字の文字列がセットされていました。

wpa_passphrase "<アクセスポイントのSSID>" "<パスワード>"
↓
network={
	ssid="<アクセスポイントのSSID>"
	#psk="<パスワード>"
	psk=<パスワード(64文字)>
}

タイムゾーン

timedatectl | grep "Time zone"
↓
Time zone: Asia/Tokyo (JST, +0900)

ロケール

locale | grep LANG
↓
LANG=C.UTF-8

あとがき

2020年3月にRaspberry Pi Imager が初めて公開された時には詳細な設定 の機能はなく、途中で機能追加されましたが、もっとシンプルなものだったような気がします。

今後もバージョンアップで機能が更に充実するかもしれないので、ブログのタイトルはバージョンを明記することにしました。

ddコマンドでディスクイメージを書き込んでいた時と比べると、何と便利になったことか。。

OpenSSHサーバでSSH,SCP,SFTP

OpenSSHサーバを使ったSFTP について書きましたが、SSHSCP について何も書いていなかったので一応書いておきます。

環境について

サーバ側の環境

  • Ubuntu

クライアント側の環境

  • macOS Monterey

OpenSSHサーバの環境構築

OpenSSHサーバのインストール

sudo apt install openssh-server

ファイアウォール

SSHの標準ポート22/TCPを開ける

sudo ufw allow ssh

コマンドの実行後の状態を確認する

sudo ufw status verbose
→ 下記の2つが追加されている
  22/tcp (OpenSSH)           ALLOW IN    Anywhere
  22/tcp (OpenSSH (v6))      ALLOW IN    Anywhere (v6)

OpenSSHサーバの設定

設定ファイルの編集

sudo vi /etc/ssh/sshd_config

/etc/ssh/ssh_config ではなく/etc/ssh/sshd_config

設定した内容(一部抜粋)※既存の設定の変更やコメントアウトなど

AllowTcpForwarding no
X11Forwarding no
Subsystem sftp  /usr/lib/openssh/sftp-server
  • Subsystem sftp はSFTP を使えないようにしたい場合は、コメントアウトする
  • Chroot でSFTPサーバを構築する場合は、Subsystem sftp/usr/lib/openssh/sftp-server ではなくinternal-sftp を指定する→「OpenSSHサーバでSFTP」参照
  • ちなみに、Subsystem sftp/usr/lib/openssh/sftp-server でもChroot なSFTPができてしまいましたが、internal-sftp を指定するのが正しいようです

設定の有効化

OpenSSH サーバを再起動

sudo systemctl restart sshd

接続確認(SSH, SCP, SFTP)

ネットワークを経由しない、サーバ内のローカル接続による接続確認です。

ssh ubuntu@localhost
→ 接続に成功
exit

echo "testdata" > testfile.txt
mkdir temp
scp testfile.txt ubuntu@localhost:temp
ls temp
→ testfile.txt が格納されている
rm temp/testfile.txt

sftp ubuntu@localhost
put testfile.txt temp/
ls temp
→ testfile.txt が格納されている
rm temp/testfile.txt
quit

接続確認(クライアントからサーバ)

サーバは、前述のローカル接続による接続確認をした後の状態で行います。
なので、/home/ubuntu にtemp ディレクトリが作られていて、中にファイルがない状態です。

接続確認(SSH)

ssh ubuntu@<hostname またはipaddress>
→ 接続に成功
exit

接続確認(SCP)

echo "testdata" > testfile.txt
scp testfile.txt ubuntu@<hostname またはipaddress>:temp

scp ubuntu@<hostname またはipaddress>:temp/testfile.txt ./testfile1.txt
ls testfile1.txt
→ testfile1.txt が格納されている
rm testfile1.txt

接続確認(SFTP)

sftp sftpuser@<hostname またはipaddress>
put testfile.txt temp/
ls temp
→ testfile.txt が格納されている
rm temp/testfile.txt
quit

あとがき

単にOpenSSHサーバを使ってSSH、SCP、SFTP を使える状態にするのは簡単にできました。

ただ、サーバを安全に管理する上では運用面をしっかりする必要がありそうです。
例えば、開発したコンテンツのアップロードだけを行う要員には、Chroot でアクセスできる範囲を制限したSFTPしか使えないユーザを割り当てるなど。

今回ははじめにのようなことを書きたかったので、この辺にしておきます。

サクラエディタで固定長を改行ありに変換

サクラエディタを使って固定長(改行なし)のテキストデータを改行ありに変換する方法を解説します。

環境

  • Windows
  • サクラエディタ(v2.4.1)※バージョンに依存しないはず

方法1. 折り返し位置に改行をつける

  1. サクラエディタで固定長(改行なし)のファイルを開 く
  2. メニューバーの[設定] > [タイプ別設定] をクリック
  3. タイプ別設定ウィンドウの[スクリーン]タブのレイアウト内で下記を指定して[OK]ボタンをクリック
    • 折り返し方法:”指定桁で折り返す”
    • 折り返し桁数:レコード長(文字数)
  4. 指定したレコード長で折り返した状態で表示される
  5. [Ctrl] + [A] で全選択
  6. メニューバーの[編集] > [折り返し位置に改行をつけてコピー]
  7. 全選択された状態で、[Ctrl] + [V] で貼り付け
  8. [Ctrl] + [S] で上書き保存

これで、指定したレコード長の固定長(改行あり)のテキストファイルが出来上がります。
上記の手順で付加される改行はCRLF になるので、LF で作成したい場合は、上書き保存する前に置換機能でCRLFLF に置換するか、名前を付けて保存で改行コードをLF で保存します。

方法2. キーマクロ

1. キーマクロファイルの作成

下記の内容を記述したテキストファイルを作成します。

S_GoFileTop(0);  // ファイルの先頭に移動
S_ReplaceAll('(.{256})', '$1¥¥r¥¥n');  // すべて置換
S_ReDraw(0);  // 再描画
  • S_ReplaceALL の第一引数に、レコード長(文字数)を指定する
  • S_ReplaceALL の第二引数に、追加する改行コードを指定する
    • CRLF の場合は ¥¥r¥¥n
    • LF の場合は ¥¥n

キーマクロのファイルは、下記の形式で保存します。

  • 改行コード:CRLF
  • 文字コード:UTF-8(BOM付)
  • ファイル名の拡張子:.mac

2. 固定長(改行なし)ファイルの変換

  1. サクラエディタで固定長(改行なし)のファイルを開く
  2. メニューバーの[ツール] > [キーマクロの読み込み] をクリック
  3. Open ウィンドウで作成したキーマクロのファイルを選択して[OK]ボタンをクリック
  4. メニューバーの[ツール] > [キーマクロの実行] をクリック
  5. [Ctrl] + [S] で上書き保存

これで、指定したレコード長の固定長(改行あり)のテキストファイルが出来上がります。
付加する改行の種類は、キーマクロのファイルで指定しておくことができます。

方法1と方法2のどちらを使うか

方法1と方法2の使い分けについて少し考えてみます。

方法1. 折り返し位置に改行をつける

感覚的に操作できるので、覚えておくと何かと便利そうです。スポットで対応する時はこちらの方法の方が素早く対応できそうです。

方法2. キーマクロ

キーマクロのファイルを準備する必要がある分、スポットでの対応には不向きかもしれませんが、定例作業や同じ作業を繰り返す場合は、一度キーマクロのファイルを準備しておけば、こちらの方が正確に素早く作業できるのではないかと思います。手順書に従って作業をする場合は、手順書とキーマクロのファイルを共有して行う感じでしょうか。

あとがき

今回解説した方法は、テキストデータに含まれる文字がASCIIコードのみであれば問題ないですが、文字コードがShift-JISでASCIIコード以外の文字を含む場合は、方法2は使えなかったりUTF-8でASCIIコード以外の文字を含む場合は、どちらも使えなかったりします。

固定長でUTF-8というのを見たことないので何ともいえませんが、UTF-8ではこの方法は使えないと考えた方が安全なのかもしれないです。

OpenSSHサーバでSFTP(公開鍵認証)

直前の投稿「OpenSSHサーバでSFTP」の続きです。
前回はパスワード認証だったので、今回は公開鍵認証でユーザ認証できるようにします。

環境について

※ 前回と同じ、サーバはUbuntu を使っています。

クライアントの環境構築

キーペアの生成

公開鍵認証で使うデジタル署名Ed25519のキーペアを生成

ssh-keygen -t ed25519
→ Your identification has been saved in /Users/xxx/.ssh/id_ed25519
   Your public key has been saved in /Users/xxx/.ssh/id_ed25519.pub
  • 任意のパスフレーズを設定します
  • 生成されるキーペアは、id_ed25519 が秘密鍵、id_ed25519.pub が公開鍵
  • キーペアのファイル名を指定したい場合は、-f オプションを使って指定します(今回は指定しなかったのでデフォルトの”id_ed25519″で作成されました)

公開鍵をサーバにアップロード

前回設定したSFTP(パスワード認証)を使ってアップロードします。
※ 公開鍵 id_ed25519.pub/var/sftp/sftpuser にアップロードします。

sftp sftpuser@<hostname またはipaddress>
→パスワードを入力してユーザ認証

cd sftpuser
put ~/.ssh/id_ed25519.pub
quit

OpenSSHサーバの環境構築

前回作成したユーザ「sftpuser」のユーザ認証の方式をパスワード認証から公開鍵認証に変更します。

公開鍵の設置

SSH接続できるユーザでサーバにSSH接続して、公開鍵を設置します。

su - sftpuser
mkdir ~/.ssh
chmod 700 ~/.ssh
cat /var/sftp/sftpuser/id_ed25519.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
exit

sudo rm /var/sftp/sftpuser/id_ed25519.pub

OpenSSHサーバの設定

設定ファイルの編集

sudo vi /etc/ssh/sshd_config

設定した内容(一部抜粋)

PubkeyAuthentication yes
AllowTcpForwarding no
X11Forwarding no
Subsystem sftp  internal-sftp

Match User sftpuser
    ChrootDirectory /var/sftp
    ForceCommand internal-sftp
    PasswordAuthentication no
    AuthorizedKeysFile /home/sftpuser/.ssh/authorized_keys
  • PasswordAuthentication no により、パスワード認証ができないようにする
  • AuthorizedKeysFile で公開鍵を指定する

設定の有効化

OpenSSH サーバを再起動

sudo systemctl restart sshd

接続確認(クライアントからサーバ)

SFTP接続の確認(成功)

Mac のターミナルを使ってネットワーク経由でSFTP接続の確認

echo "test" > testfile.txt

sftp -i ~/.ssh/id_ed25519 sftpuser@<hostname またはipaddress>
→パスフレーズを入力して公開鍵認証

cd sftpuser
put testfile.txt
ls
quit

SSHとSCP接続の確認(失敗)

SSHの接続を試してみると失敗します

ssh -i ~/.ssh/id_ed25519 sftpuser@<hostname またはipaddress>
→パスフレーズを入力して公開鍵認証
→ This service allows sftp connections only.

SCPの接続を試してみると失敗します

scp -i ~/.ssh/id_ed25519 testfile.txt sftpuser@<hostname またはipaddress>:
→パスフレーズを入力して公開鍵認証
→ This service allows sftp connections only.

あとがき

パスワード認証の場合、パスワードが漏洩すると第三者がログインできてしまいますが、公開鍵認証はクライアント上に保存した暗号鍵とパスフレーズの両方が第三者の手に渡らなければ第三者によるログインが成功しないので、より安全なユーザ認証の方式といえると思います。

設定がパスワード認証に比べると面倒かもしれませんが、なるべく公開鍵認証を使うようにした方がよいのでしょう。

OpenSSHサーバでSFTP

クライアント上のファイルをサーバにSFTPでアップロードできるようにします。
今回解説する手順は、SFTP専用のユーザを作成して、Chrootにより限定された場所にファイルをアップロードできるようにする手順となります。

環境について

サーバ側の環境

  • Ubuntu
  • OpenSSHサーバ ※インストール済み

クライアント側の環境

  • macOS Monterey

OpenSSHサーバの環境構築

SFTP専用ユーザーの作成

sudo adduser sftpuser

ユーザ認証はパスワード認証を使うので、任意のパスワードを設定します。
※ 公開鍵認証も可能ですが、SFTP中心の解説にしたいので省略します。

SFTP専用グループの作成

sudo groupadd sftponly

ユーザをグループに追加 ※セカンダリグループ

sudo adduser sftpuser sftponly

SFTP専用ディレクトリの作成

SFTP専用ディレクトリの作成 ※Chrootディレクトリ

sudo mkdir /var/sftp
sudo chown root:root /var/sftp

SFTP専用ユーザのディレクトリの作成 ※ここにアップロードする

sudo mkdir /var/sftp/sftpuser
sudo chown sftpuser:sftponly /var/sftp/sftpuser
sudo chmod 755 /var/sftp/sftpuser

OpenSSHサーバの設定

設定ファイルの編集

sudo vi /etc/ssh/sshd_config

/etc/ssh/ssh_config というファイルもあるけれども、設定するのは/etc/ssh/sshd_config

設定した内容(一部抜粋)※既存の設定の変更やコメントアウトなど

AllowTcpForwarding no
X11Forwarding no
Subsystem sftp  internal-sftp

設定した内容 ※末尾に追記

Match User sftpuser
    ChrootDirectory /var/sftp
    ForceCommand internal-sftp
    PasswordAuthentication yes
  • ChrootDirectory は、SFTP接続した際のルートディレクトリを/var/sftp に設定する
  • ForceCommand internal-sftp により、SFTP の利用に限定する(SSHとSCPが使えない)
  • ChrootDirectoryForceCommand internal-sftp の両方を設定することでChroot とSFTP 限定が有効になるようです

設定の有効化

OpenSSH サーバを再起動

sudo systemctl restart sshd

接続確認

サーバのローカル環境上でのSFTP接続の確認

sftp sftpuser@localhost

接続確認(クライアントからサーバ)

SFTP接続の確認(成功)

Mac のターミナルを使ってネットワーク経由でSFTP接続の確認

echo "test" > testfile.txt

sftp sftpuser@<hostname またはipaddress>
→パスワードを入力してユーザ認証

pwd
→ Remote working directory: /
put testfile.txt
→ remote open("/testfile.txt"): Permission denied
cd sftpuser
put testfile.txt
ls
quit
  • 接続した時点のカレントディレクトリは/var/sftp がルートディレクトリとなっていて、ディレクトリの所有者とグループがroot なのでput でファイルをアップロードしようとすると失敗します。
  • cd でカレントディレクトリを/var/sftp/sftpuser に変えてからput するとアップロードが成功します。

SSHとSCP接続の確認(失敗)

SSHの接続を試してみると失敗します

ssh sftpuser@<hostname またはipaddress>
→ This service allows sftp connections only.

SCPの接続を試してみると失敗します

scp testfile.txt sftpuser@<hostname またはipaddress>:
→ This service allows sftp connections only.

あとがき

ChrootDirectory/var/sftp としましたが、ユーザのホームディレクトリ/home/sftpuser を指定してもよさそうです。

SFTPでファイルのアップロード・ダウンロードをするのが専用のユーザなので、SSH接続できるユーザがそのファイルのコピー等をするのにどこが運用上望ましいかで判断する感じでしょうか。