EC2 Instance ConnectをAmazon Linux以外で使う方法を調べてみた

2023.08.09

はじめに

こんにちは。CX事業本部Delivery部のakkyです。

EC2 Instance Connectを使用すると、マネジメントコンソールやAWS CLIからEC2インスタンスにSSH接続できてとても便利です。

最近登場したEC2 Instance Connect Endpointを併用すると、プライベートサブネットへも踏み台無しで接続できるようになるような便利なアップデートもされています。

ところで、EC2 Instance Connectは単なるWeb SSHコンソールではないことをご存じでしょうか?その証拠に、インスタンスに公開鍵を設定しなくても接続することができます。

これは接続時に公開鍵を転送しているためなのですが、このためにはインスタンスにEC2 Instance Connect Configurationというソフトウェアがインストールされている必要があります。(名前が同じですし併用するのでわかりづらいですが、EC2 Instance Connect EndpointはただのTCPトンネルとして使うことができます。この場合はインスタンスに追加ソフトウェアは不要ですが、公開鍵は別途必要です。)

https://github.com/aws/aws-ec2-instance-connect-config

EC2 Instance Connect ConfigurationはAmazon LinuxやUbuntuのAMIには最初からインストールされているのですが、他のLinuxディストリビューションでもマネジメントコンソールから接続できればとても便利そうです。

幸いなことに、EC2 Instance Connect Configurationはシェルスクリプトで実装されていて、SSHデーモン(OpenSSH)に設定を加えることができれば動くので、他のディストリビューションでも使うことができます。 今回は、標準サポートしているrpmとdebパッケージを作ってインストールし、SELinuxの設定を行うことで接続ができることを確認しました。

恐らく、rpmやdeb以外のパッケージ形式を使うディストリビューションでも設定さえできれば動くと思うのですが、今回は検証していません。

前提条件

2023/8/8にダウンロードしたaws-ec2-instance-connect-config(551c73e8ec1f5ade4c8b1f52cf616e75b47879b4)を使いました。以下の作業方法で1.1.18や19が混在していますが、リポジトリに由来するものです。

EC2はt3インスタンス(x86_64)で検証しました。シェルスクリプトで動作するのでARMインスタンスでも動作する可能性が高いです。

動作確認にはマネジメントコンソール(EC2コンソール)のEC2 Instance Connect機能を使用しました。(CLIからはチェックしていません。また指定した鍵の転送もチェックしていません。)

注意事項

EC2 Instance Connect ConfigurationがAWS公式にサポートされているのはAmazon Linux2とUbuntu16.04以降のみであり、その他のディストリビューションでの使用はサポートされていません。自己責任でご使用ください。また、SELinuxの設定はご自身でよくご確認ください。

公式サポート

Amazon Linux2, 2023, Ubuntu 20.04 AMI

Amazon Linux 2とUbuntu 20.04の公式AMIには、EC2 Instance Connectがプリインストールされています。

また、ドキュメントに記載されていませんがAmazon Linux 2023にもプリインストールされていました。

Ubuntu 16.04

Ubuntu 16.04では、公式ドキュメントに記載の手順でインストールする必要があります。(aptでインストールするだけです)

非公式

openSUSE / SUSE

AWS非公式ですが、ec2-instance-connectパッケージが用意されていますので、以下のコマンドを実行すれば利用できるようになります。

sudo zypper install ec2-instance-connect

openSUSE Leap 15.5で動作確認できました。

AlamaLinux 8/9 (RHEL派生)

ここが本記事のメインです!

AlmaLinuxにはパッケージが用意されていませんので、自分でビルドする必要があります。 ec2-instance-connect-configはシェルスクリプトで作られていて、Makefileでrpmとdebパッケージを生成することができるので、makeしてrpmインストールすれば終わり!・・・と思ったのですが、これだけでは動きませんでした。

というのも、AlmaLinuxではSELinuxが利用されているので、sshdが通常とは異なるコマンドを実行するec2-instance-connectはブロックされてしまいます。 手軽に動かすならSELinuxを無効化してしまえばいいのですが、今回はSELinuxのブーリアンやポリシーを設定して、SELinuxがEnforceの状態で動くようにしてみました。

Rocky LinuxやOracle Linuxなど、他のRHEL派生ディストリビューションでも動くはずですが、未検証です。

必要なパッケージ

SELinuxのビルドに必要なselinux-policy-develとパッケージの取得とビルドに使うgit、rpm-buildをインストールしておきます。 なお、ほとんどの作業をrootで行う必要があるので、sudo -sしておきます。

dnf -y install selinux-policy-devel git rpm-build

ec2-instance-connectのビルドとインストール

リポジトリをクローンしてきてmake rpmし、インストールします。

git clone https://github.com/aws/aws-ec2-instance-connect-config
cd aws-ec2-instance-connect-config/
make rpm
rpm -i rpmbuild/RPMS/noarch/ec2-instance-connect-1.1-18.noarch.rpm

SELinuxの設定

SELinuxの理解には「SELinuxのせいで動かない」撲滅ガイドが非常に参考になりました。

インストール後、接続を試行しつつsetroubleshootを使用して必要な権限を探しました。

setroubleshootをインストールすると/var/log/messagesにヒントが残りますので、これを参考にブーリアンを変更したり、設定ファイルを作ります。なお、コマンドの実行に途中で失敗しているため、一度設定しても同名の設定ファイルを再び作れと言われることがあります。この際には新たな権限が追加されているはずです。

今回はブーリアンがあるものは使用し、それ以外をポリシーファイルを作ってみました。

なお、私はSELinuxに精通しているわけではありませんので、権限が不用意に拡大している可能性があります。使用する際にはよくご確認ください。

まず、ブーリアンを設定します。

setsebool -P authlogin_yubikey 1
setsebool -P nis_enabled 1
setsebool -P domain_can_mmap_files 1

次にポリシーファイルを作ります。my-eic.teというファイル名で保存します。

my-eic.te

module my-eic 1.0;

require {
        type sshd_t;
        type ssh_keygen_exec_t;
        class file { execute execute_no_trans open read };
        class process setpgid;
}

#============= sshd_t ==============
allow sshd_t ssh_keygen_exec_t:file execute_no_trans;
allow sshd_t ssh_keygen_exec_t:file { execute open read };
allow sshd_t self:process setpgid;

teファイルをビルドしてppファイルにします。

make -f /usr/share/selinux/devel/Makefile

次のコマンドでポリシーをインストールします。

semodule -i my-eic.pp

この手順でEC2 Instance Connectで接続できるようになりました!

Debian 12

DebianにはSELinuxはありませんので、手順は簡単です。

まず、必要なパッケージをインストールします。

sudo apt install git make devscripts

AlamaLinuxのときと同様にgit cloneしてきてビルドします。make debとなっているのが異なる点です。

git clone https://github.com/aws/aws-ec2-instance-connect-config
cd aws-ec2-instance-connect-config/
make deb

なお、make deb実行後に以下のようなメッセージが表示されて失敗しますが、署名ができなかっただけでローカルでインストールする分には大丈夫なようです。

Now signing changes and any dsc files...
 signfile dsc ec2-instance-connect_1.1.19.dsc Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
gpg: directory '/home/admin/.gnupg' created
gpg: keybox '/home/admin/.gnupg/pubring.kbx' created
gpg: skipped "Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>": No secret key
gpg: /tmp/debsign.QFqRUyHY/ec2-instance-connect_1.1.19.dsc: clear-sign failed: No secret key
debsign: gpg error occurred!  Aborting....
debuild: fatal error at line 1112:
running debsign failed

最後にインストールします。

sudo dpkg -i ec2-instance-connect_1.1.19_all.deb

これで接続できるようになりました!

おわりに

EC2 Instance ConnectをAmazon Linux2やUbuntu以外でも使えることを確認できました。また、インストールや設定の過程で動作の仕組みも知ることができました。

EC2 Instance Connectは公開鍵不要でSSH接続できてとても便利なうえ、EC2 Instance Connect Endpointを組み合わせればプライベートサブネットからでも使えるという管理もコストもやさしいサービスなので、皆さんもぜひ活用してみてください。