🐧

macOSのリモート開発サーバーとしてのUbuntuデスクトップ

2023/07/31に公開

この記事を通して、Linux(Ubuntu)をリモート開発サーバーにする方法と、1Password の SSH Agent Forwarding 機能を使って SSH キーの管理を 1Password におまかせしてセキュアに SSH 接続できるようになります。

過去に脱 macOS して Linux に乗り換えようと試みたものの、macOS では Karabiner-Elements を使って HHKB のキーバインドをいじくっており、このキーバインドを Ubuntu で再現するのがかなり面倒で断念してしまいました。そういうわけで使っていない Linux のマシンが部屋に転がっており、普段使っている MacBook Pro が 5 年前に買ったものなので開発環境としてはやや力不足なため、お金をかけずに改善しようと思ったのがきっかけです。

SSH 接続するために最低限やること

まずは Ubuntu デスクトップに SSH 接続できるようにします。Ubuntu デスクトップ上で以下を実行します。

SSH サーバーをインストールします。

sudo apt-get update
sudo apt-get install openssh-server

インストールができたら SSH サービスが起動していることを確認します。Active: active (running) になっていれば OK です。

sudo systemctl status ssh

次に、クライアント側から SSH 接続してみます。

USERNAME や HOST の確認方法、NIC の意味合いについて

USERNAME は Ubuntu デスクトップ上で whoami コマンドから、HOSTip address show コマンドから確認できます。

ip address show コマンドから NIC が確認できますが、この命名規則は Predicatable Network Interface Names に基づいているようです。例を以下に示します:

  • enp1s0: en = Ethernet、p1 = PCI バス 1、s0 = スロット 0
  • wlp2s0: wl = WirelessLAN、p2 = PCI バス 2、s0 = スロット 0
ssh {USERNAME}@{HOST}
トラブルシューティング: 接続できなかったら

①SSH サービスが起動していること。Active でなければ systemctl start なり reload なり実行します。

sudo systemctl status ssh

② ネットワーク接続ができていること。

ping {HOST}

③ ファイアウォール設定を確認。デフォルトでは 22 番ポートが使われるため 22 番ポートが ALLOW になっていないと疎通ができません。

sudo ufw status

# リストに加えられていなければ
sudo ufw allow ssh

セキュリティまわり

このままだと、USERNAME と HOST が割れてしまった場合、好き放題 SSH 接続できてしまうのでもうちょっとちゃんとやる必要があります。

以下の項目は少なくとも考慮しておく必要があります。

  • ポート番号の変更
  • ルートユーザーでのログインを塞ぐ
  • パスワードでのログインを塞ぐ

ポート番号の変更

ポート番号のデフォルトである 22 から例として 10022 に変更してみます。Ubuntu デスクトップの /etc/ssh/sshd_config ファイルを以下のように編集します。

Port 10022

そうしたら SSH サービスの再起動とファイアウォールの許可を行います。

sudo systemctl restart ssh
sudo ufw allow 10022

一旦ログアウトして、クライアント側から SSH 接続を試行します。

ssh -p 10022 {USERNAME}@{HOST}

問題なく 10022 番で接続できていた場合は、もう使わなくなった 22 番ポートを削除します。

sudo ufw delete allow 22

これで無事に 22 番から 10022 番に変更することができました。さらに、SSH 接続元をホームネットワーク内に限定したい場合は「Tips: SSH 接続元をホームネットワークに限定する」を参照してください。

ルートユーザーでのログインを塞ぐ

Ubuntu デスクトップの /etc/ssh/sshd_config ファイルを以下のように編集します。

PermitRootLogin no

そうしたら SSH サービスの再起動をして終わりです。

sudo systemctl restart ssh

パスワードでのログインを塞ぐ

パスワードでのログインから SSH キーでの認証に切り替えます。このときすでに 1Password を利用している場合は「Tips: 1Password を用いた SSH キーのフォワーディング」で対応することも可能です。

まず、Ubuntu デスクトップの ~/.ssh/authorized_keys ファイルにクライアント側のマシンの公開鍵の内容をコピーします。ここでは公開鍵の名前は id_rsa.pub とします。

ssh-copy-id -i ~/.ssh/id_rsa.pub {USERNAME}@{HOST}

次に、SSH サーバー上で /etc/ssh/sshd_config ファイルを以下のように編集します。

PasswordAuthentication no
PubkeyAuthentication yes

そうしたら SSH サービスの再起動をして終わりです。

sudo systemctl restart ssh

Tips: SSH 接続元をホームネットワークに限定する

ホワイトリスト形式で接続元を絞りたい場合はファイアウォールで特定の IP アドレス範囲に限定してしまいましょう。たとえば inet が 192.168.1.5 で netmask が 0xffffff00 の場合の CIDR は 192.168.1.0/24 になります。

sudo ufw allow from 192.168.1.0/24 to any port 10022

Anywhere で許可されている 10022 番のファイアウォールは削除してしまいましょう。また IPv6 に関して Anywhere な設定が残っているかもしれないので使わない場合は許可しておく必要がないので削除してしまいましょう。

sudo ufw delete allow 10022
既存の設定を簡単に削除するには…?

ufw コマンドの長い呪文みたいなのを唱えなくとも既存のファイアウォール設定を削除する方法があります。numbered をつけることで番号が分かるので番号を指定して削除することができます。

$ sudo ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 10022                      ALLOW IN    Anywhere
[ 2] 10022                      ALLOW IN    192.168.1.0/24
[ 3] 10022 (v6)                 ALLOW IN    Anywhere (v6)

こんな感じで番号を指定して削除することができます。いらないファイアウォール設定を追加してしまったときなど簡単に削除できるので役に立つかもしれません。

sudo ufw delete 2

ufw コマンドについてはこの記事が詳しく書かれていて参考になります。

https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-ubuntu-22-04

Tips: 1Password を用いた SSH キーのフォワーディング

パスワードやクレデンシャルなどは全部 1Password に管理させているので SSH キーも管理させてしまいたいです。さらに、Ubuntu デスクトップから GitHub にコードを push したりする際に新しく SSH キーを作ることもしたくないので、1Password で管理している SSH キーを使い回せるようにします。

1Password の SSH Agent を有効にする方法は以下を参照してください。
https://developer.1password.com/docs/ssh/get-started/

1Password で SSH キーの作成、あるいはインポートができたら Ubuntu デスクトップの ~/.ssh/authorized_keys ファイルに 1Password で管理し始めた SSH キーの公開鍵の内容をコピーします。もし、クライアント側で生成した公開鍵の内容が記載されていて不要であれば置換しても構いません。

そうしたらクライアント側で ~/.ssh/config ファイルを開き以下の内容を貼り付けます。IdentityAgent の値に関してはすぐ上のドキュメントのStep 4で指定しているものと同じです。

Host {HOST_ALIAS}
	HostName {HOST}
	User {USERNAME}
	Port {PORT}
	IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
	ForwardAgent yes

これで 1Password に SSH キーの管理を任せて SSH 接続ができるようになります。1Password の設定によっては以下のコマンドの後に SSH キーの使用を許可するかどうかのポップアップが出るかもしれません。

ssh {HOST_ALIAS}

SSH キーがフォワードされているかどうかは、Ubuntu デスクトップで以下より確認できます。フォワードされていない場合は Could not open a connection to your authentication agent. と返ってきます。

ssh-add -l

Tips: Ubuntu デスクトップの GUI の無効化

今回は Ubuntu デスクトップをリモートサーバー化したため GUI が使える状態です。CPU やメモリなどを消費してしまうため、GUI を使わないのであれば無効にしてしまうのも一つの手です。今回は、後から GUI での操作に戻れるように後戻りの効く方法を紹介します。

Ubuntu デスクトップで runlevel コマンドを叩いてランレベルを確認します。GUI が起動しているので N 5 という出力になるはずです。

ランレベルとは
  • ランレベル 0: システムを停止(シャットダウン)
  • ランレベル 1: シングルユーザーモード。基本的なシェルが利用可能で、システム管理者(root ユーザー)だけがログインできるモード。ネットワークや他のサービスは無効になっている。
  • ランレベル 2: Ubuntu のデフォルトランレベル。ほとんどのネットワークサービスとマルチユーザーサポートを含む全てのサービスが動作している状態。通常は GUI は含まれない
  • ランレベル 3-5: ランレベル 2 と同じ機能を提供し、設定によっては GUI が起動することもある。ランレベル 2 との明確な差はない
  • ランレベル 6: システムを再起動

ランレベルは 3 で十分なので 3 に落とします。変更後は再起動が必要です。

sudo systemctl set-default multi-user.target

なお、ランレベルを 5 に戻す場合は以下です。

sudo systemctl set-default graphical.target

最後に

かなり丁寧めにまとめたので詰まらずにできるんじゃないかと期待していますが、「ここどうやるんだ?」と思うようなことがあればコメントもお待ちしています。

ちょっとでも役に立つところがあれば Like もお願いします!

Discussion