SSHのOTP認証を自動突破する

筑波大学のスーパーコンピューターのSSHは公開鍵認証に加え、OTPによる認証があるが毎回パスワード入力するのが本当に面倒。

認証自動化

OTPは1passwordで管理しているのでotp自体は1password cli経由で取れる。面倒なのはsshコネクションでの自動化だが、これはexpect(1) で自動化できる。 スクリプトはこんな感じ

#!/usr/bin/expect

set timeout 5

set cmd [lrange $argv 1 end]
set password [lindex $argv 0]
eval spawn $cmd
expect "Verification code:"
send "$password\r";
interact 

使い方はこう。これを適当なシェルスクリプトにしておくとコマンド一発で入れて便利。

ssh-with-otp "$(op read "op://Personal/supacon/otp?attribute=otp")" ssh [email protected] 

ControlMaster

でもexpectによる自動化ではvscodeのremote sshはどうにもならず困っていたところ、Slackで指導教員からControlMaster を教えてもらった。

Host supacon.sugoi.ac.jp
    User user
    ControlMaster auto
    ControlPath ~/.ssh/mux-%r@%h:%p.sshsock
    ControlPersist 3h 

これControlMasterがあれば最初の一回だけOTP入れればいいから自動化とか要らないんじゃないかという気もするが、 最初の一回だけでも既に面倒なので一応意味はありそう。 スクリプトを下記のように書き換えればControlMasterのソケットがない時だけOTPを使ってログインするように出来る。

#!/bin/sh

user=user
host=supacon.sugoi.ac.jp
port=22

if [ ! -e "$HOME/.ssh/mux-$user@$host:$port.sshsock" ]; then
  OTP="$(op read "op://Personal/supacon/otp?attribute=otp")"
  ssh-with-otp "$OTP" ssh "$user@$host" -p "$port"
else
  ssh "$user@$host" -p "$port"
fi