時折、リモートサーバにある"ログインユーザでは読み取りができないファイル"をそのままローカルにコピーしたいことがある。 ssh経由でファイルをコピーするといえばscpがよく使われる方法だと思うが、残念ながらscpではリモートサーバ側でsudoを使ってroot権限でファイルを読み込んだりといった事はできない。 さて、じゃどうすればいいのだろうか。
こういったとき、sudoをNOPASSWDで実行可能な状態であれば、単体のファイルであればsshコマンドからsudoを使ってcatで、ディレクトリごとであれば一度tarでアーカイブ化してローカルでそのまま展開させる事ができる。 なお、RHEL系のデフォルトではsudo実行には擬似端末が必要になる(AWSやAzureのCentOSイメージでは手が加えてある様子)のだが、catコマンドはsshコマンド実行時に-ttの付与しておけば良いのだが、tarに関しては擬似端末を利用してのssh越しの実行ができない。 このため、/etc/sudoersにてrequirettyを無効化しておく必要があるので注意。
ssh -t user@host 'sudo cat RemoteFile.path' > LocalFile.path # 単体ファイルの場合
ssh user@host 'sudo tar -C RemoteSourceDir czf - .' | tar -C LocalDestinationDir -xzf - # ディレクトリの場合
blacknon@BS-PUB-DEVELOP:~$ ssh -t test@BS-PUB-CENT7-01 'cat /var/log/secure'
cat: /var/log/secure: 許可がありません
Connection to bs-pub-cent7-01 closed.
blacknon@BS-PUB-DEVELOP:~$ ssh -t test@BS-PUB-CENT7-01 'sudo cat /var/log/secure' > ./secure
Connection to bs-pub-cent7-01 closed.
blacknon@BS-PUB-DEVELOP:~$ tail secure
Jun 12 11:30:58 BS-PUB-CENT7-01 sudo: pam_unix(sudo:auth): auth could not identify password for [test]
Jun 12 11:30:58 BS-PUB-CENT7-01 sshd[21013]: Received disconnect from 172.28.0.171: 11: disconnected by user
Jun 12 11:30:58 BS-PUB-CENT7-01 sshd[21010]: pam_unix(sshd:session): session closed for user test
Jun 12 11:31:01 BS-PUB-CENT7-01 sshd[21118]: Accepted publickey for test from 172.28.0.171 port 46934 ssh2: RSA 81:0c:f5:73:11:2e:e7:d7:8d:4c:fd:b5:cc:3d:40:f5
Jun 12 11:31:03 BS-PUB-CENT7-01 sshd[21118]: pam_unix(sshd:session): session opened for user test by (uid=0)
Jun 12 11:31:04 BS-PUB-CENT7-01 sshd[21121]: Received disconnect from 172.28.0.171: 11: disconnected by user
Jun 12 11:31:04 BS-PUB-CENT7-01 sshd[21118]: pam_unix(sshd:session): session closed for user test
Jun 12 11:31:06 BS-PUB-CENT7-01 sshd[21138]: Accepted publickey for test from 172.28.0.171 port 46936 ssh2: RSA 81:0c:f5:73:11:2e:e7:d7:8d:4c:fd:b5:cc:3d:40:f5
Jun 12 11:31:08 BS-PUB-CENT7-01 sshd[21138]: pam_unix(sshd:session): session opened for user test by (uid=0)
Jun 12 11:31:09 BS-PUB-CENT7-01 sudo: test : TTY=pts/2 ; PWD=/home/test ; USER=root ; COMMAND=/bin/cat /var/log/secure
blacknon@BS-PUB-DEVELOP:~$ ssh test@BS-PUB-CENT7-01 'sudo tar -C /var/log -czf - .' | tar -C ./testLogDir/ -xzf -
blacknon@BS-PUB-DEVELOP:~$ ls testLogDir/
anaconda cron-20170604 lastlog messages-20170529 secure-20170604 tuned
audit cron-20170612 maillog messages-20170604 secure-20170612 wpa_supplicant.log
boot.log dmesg maillog-20160306 messages-20170612 spooler wtmp
btmp dmesg.old maillog-20170529 nginx spooler-20160306 wtmp.bk
btmp-20170601 firewalld maillog-20170604 ppp spooler-20170529 yum.log
cron grubby maillog-20170612 secure spooler-20170604
cron-20160306 grubby_prune_debug messages secure-20160306 spooler-20170612
cron-20170529 httpd messages-20160306 secure-20170529 tallylog
なお、この時sudo実行時にパスワードが必要な場合、以下のように標準入力から受付けさせるようにする。 この際標準エラー出力を/dev/nullに吐かせないと、sudoのパスワード入力プロンプトがリダイレクト先に出力されてしまうので注意。 (サンプルでは、量が多くなるのでtailで取得している)
ssh -t user@host 'echo Password |sudo -S cat RemoteFile.path 2>/dev/null' > LocalFile.path # パイプで渡す場合
ssh -t user@host 'sudo -S cat RemoteFile.path 2>/dev/null' > LocalFile.path # プロンプト等出ないが、そのままパスワードを入力
ssh user@host 'echo Password | sudo -S tar -C RemoteSourceDir -czf - . 2>/dev/null' | tar -C LocalDestinationDir -xzf - # パスワードをパイプで渡してディレクトリごと取得する場合
blacknon@BS-PUB-DEVELOP:~$ ssh -t blacknon@BS-PUB-UBUNTU-01.blacknon.local 'sudo -S tail -5 /var/log/syslog 2>/dev/null' > tail_test3.log
blacknon@bs-pub-ubuntu-01.blacknon.local's password:
Connection to bs-pub-ubuntu-01.blacknon.local closed.
blacknon@BS-PUB-DEVELOP:~$ cat tail_test3.log
Jun 13 00:07:50 BS-PUB-UBUNTU-01 systemd[1]: Started Session 3347 of user blacknon.
Jun 13 00:08:10 BS-PUB-UBUNTU-01 systemd[1]: Started Session 3348 of user blacknon.
Jun 13 00:08:33 BS-PUB-UBUNTU-01 systemd[1]: Started Session 3349 of user blacknon.
Jun 13 00:10:13 BS-PUB-UBUNTU-01 systemd[1]: Started Session 3350 of user blacknon.
Jun 13 00:10:27 BS-PUB-UBUNTU-01 systemd[1]: Started Session 3351 of user blacknon.
blacknon@BS-PUB-DEVELOP:~$
blacknon@BS-PUB-DEVELOP:~$ ssh -t blacknon@BS-PUB-UBUNTU-01.blacknon.local 'echo Password | sudo -S tail -5 /var/log/syslog 2>/dev/null' > tail_test3.log
blacknon@bs-pub-ubuntu-01.blacknon.local's password:
Connection to bs-pub-ubuntu-01.blacknon.local closed.
blacknon@BS-PUB-DEVELOP:~$ cat tail_test3.log
Jun 13 00:10:48 BS-PUB-UBUNTU-01 sm-mta[29803]: v57LUkgo005932: to=<root@BS-PUB-UBUNTU-01.BLACKNON.LOCAL>, delay=4+17:40:01, xdelay=00:00:00, mailer=local, pri=61410000, dsn=4.0.0, stat=Operating system error
Jun 13 00:10:48 BS-PUB-UBUNTU-01 sm-mta[29825]: v57LP2gm005928: Warning: program /usr/sbin/sensible-mda unsafe: No such file or directory
Jun 13 00:10:48 BS-PUB-UBUNTU-01 sm-mta[29825]: v57LP2gm005928: SYSERR(root): Cannot exec /usr/sbin/sensible-mda: No such file or directory
Jun 13 00:10:48 BS-PUB-UBUNTU-01 sm-mta[29803]: v57LP2gm005928: to=<root@BS-PUB-UBUNTU-01.BLACKNON.LOCAL>, ctladdr=<root@BS-PUB-UBUNTU-01.BLACKNON.LOCAL> (0/0), delay=4+17:45:46, xdelay=00:00:00, mailer=local, pri=61501361, dsn=4.0.0, stat=Operating system error
Jun 13 00:10:52 BS-PUB-UBUNTU-01 systemd[1]: Started Session 3352 of user blacknon.
blacknon@BS-PUB-DEVELOP:~$ ssh -i testkey blacknon@BS-PUB-UBUNTU-01.blacknon.local 'echo Password | sudo -S tar -C /var/log -czf - . 2>/dev/null' | tar -C ./testLogDir2 -xzf -
blacknon@BS-PUB-DEVELOP:~$ ls -a testLogDir2
. auth.log dmesg.1.gz faillog mail.err.1 syslog.1
.. auth.log.1 dmesg.2.gz fontconfig.log mail.err.2.gz syslog.2.gz
alternatives.log auth.log.2.gz dmesg.3.gz fsck mail.err.3.gz syslog.3.gz
alternatives.log.1 auth.log.3.gz dmesg.4.gz installer mail.err.4.gz syslog.4.gz
alternatives.log.2.gz auth.log.4.gz dpkg.log kern.log mail.log syslog.5.gz
alternatives.log.3.gz boot.log dpkg.log.1 kern.log.1 mail.log.1 syslog.6.gz
alternatives.log.4.gz bootstrap.log dpkg.log.2.gz kern.log.2.gz mail.log.2.gz syslog.7.gz
alternatives.log.5.gz btmp dpkg.log.3.gz kern.log.3.gz mail.log.3.gz unattended-upgrades
apport.log btmp.1 dpkg.log.4.gz kern.log.4.gz mail.log.4.gz upstart
apport.log.1 dist-upgrade dpkg.log.5.gz landscape maltrail wtmp
apport.log.2.gz dmesg dpkg.log.6.gz lastlog mysql wtmp.1
apt dmesg.0 dpkg.log.7.gz mail.err syslog