私は次のタスクを持っています:
私は何日もグーグルで検索しましたが、これに対する解決策を見つけることができないようです。
ここで提案された解決策: サーバーにSSHしてユーザーを切り替え、ディレクトリを変更する
ssh -t username@hostname "Sudo su - otheruser -c \"cd /path/to/directory && command\""
サーバーでSudoが無効になっているため機能しません:
誰かがこれに対する解決策を持っていますか?
おそらく少し外れたトピックかもしれませんが、これはPythonとparamikoモジュールで達成できます:
#!/usr/bin/python2
import time
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_Host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('127.0.0.1', port=22, username='user', password='pass')
stdin, stdout, stderr = ssh.exec_command('su')
time.sleep(0.1) # some enviroment maybe need this.
stdin.write('root_password_goes_here\n')
[ add extra code here to execute a command ]
stdin.flush()
print (stdout.readlines())
ssh.close()
スクリプトにパスワードを保存することは、一般にセキュリティの観点からは悪い考えです。スクリプトに適切な権限が設定されていることを確認してください(例:chmod 740)
SSH経由で(非特権ユーザーとして)ログインし、引数なしでsu
コマンドを実行してrootユーザーに変更します。これを行うには、rootパスワードが必要です。次に、実行するコマンドを実行します。
編集: 1行で実行したい場合は、以下を使用できます。ssh username@hostname "su -c \"code_here\""
これが機能しない場合は、passwd
をrootとして実行して、rootパスワードが有効になっていることを確認してください。これにより、新しいrootパスワードが要求されます。
補足: root以外の別のユーザーとしてコマンドを実行するには(ターゲットユーザーのパスワードが必要であることに注意してください):ssh username@hostname "su - username_of_target -c \"code_here\""
Rootパスワードをスクリプトに入力するよりもセキュリティの悪夢が少ない場合は、setuid
実行可能ファイルを使用できます。
setuid
実行可能ファイルは、実行するユーザーに関係なく、rootとして実行されます。
これの主な利点は、誰かがあなたのラップトップを盗んだ場合、彼らはrootとしてsmartctl -a /dev/sda
を実行できますが、それ以外の場合はあなたのユーザー特権しか持っていないということです。または、後で説明するように強制コマンドで公開鍵を設定した場合はさらに少なくなります。
次のように、必要なスクリプトまたはプログラムを実行する単純なCプログラムsmartctl_wrapper.c
を記述します。
#include <unistd.h>
int main() {
//depending on your use case, you may want
//setuid(0), setgid(0), and/or setegid(0) here
execl("/full/path/to/smartctl","smartctl","-a","/dev/sda",(char*) NULL);
}
そして、それをgcc smartctl_wrapper.c -o smartctl_wrapper
としてコンパイルします。
次に、これをrootと、それを実行できるはずのグループに属させます。これらのコマンドはrootとして実行する必要があります。
chown root:some_group smartctl_wrapper
次に、それをsetuid
実行可能ファイルにします。また、ユーザーが編集できないようにします。
chmod 4510 smartctl_wrapper
これは、パスワードを必要とせずに、ルート権限を持つsome_group
のすべてのメンバーが実行できる実行可能ファイルになりました。
これで、sshで簡単に実行できます。
ssh [email protected] /path/to/smartctl_wrapper
サーバーで許可されている場合は、公開鍵を使用してssh接続をセットアップし、パスワードなしの接続を許可できます。 強制コマンド を使用して、このキーをこのスクリプトの実行以外の目的で使用することもできます。
サーバーで許可されていない場合は、代わりにsshパスワードを使用してスクリプトを作成できます。この場合、最小限の権限と/sbin/nologin
のログインシェルで、このためだけに新しいユーザーを作成することを強くお勧めします。
または、特定のユースケースでは、ssh
を介してrootとしてコマンドを完全に実行しないことをお勧めします。たとえば、cron
を使用してこのコマンドを定期的に実行するようにスケジュールできます。ルートのcrontabは次のように編集できます。
su -c crontab -e -u root
そして行を追加します:
5 0 * * Sun smartctl -a /dev/sda >> /some/path/to/log/some/non/root/user/can/read
指定された行は、週に1回、日曜日の午前0時の5分後にコマンドを実行します。 crontab(5) の指示に従って、これを好みに応じて調整できます。
次に、ssh
を使用してログを読み取ることができます。
対話型セッションでは、paramiko invoke Shellコマンドを使用することもできます。 https://www.youtube.com/watch?v=lLKdxIu3-A4
import paramiko
from paramiko.channel import Channel
import time
ssh = paramiko.SSHClient()
ssh.set_missing_Host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('ip', port=22, username='non-root', password='non-root-password')
channel:Channel = ssh.invoke_Shell()
print(type(channel))
channel_data = str()
while True:
if channel.recv_ready():
time.sleep(2)
channel_data += str(channel.recv(999))
else:
continue
channel.send("whoami\n")
time.sleep(2)
channel_data += str(channel.recv(999))
channel.send("su\n")
time.sleep(5)
channel_data += str(channel.recv(999))
# if "Password" in channel_data:
channel.send("rootpaasword\n")
time.sleep(2)
channel_data += str(channel.recv(999))
channel.send("whoami\n")
time.sleep(2)
channel_data += str(channel.recv(999))
# channel_data += str(channel.recv(999))
break
print(channel_data)
それで、4時間の追加のWebクロールの後に、ようやくそれができました! Bigこれについての洞察を提供してくれた@ jeroen-it-nerdboxに感謝:
タスクは、smart-ctl(ルート資格情報が必要)から、ssh-rootが無効でSudoが無効になっているサーバーからデータを取得することでした。もちろん、これはsuではなくSudoでも機能します。
Pythonで実行可能な完全なコードで、Paramikoを実装しています。
#!/usr/bin/python2
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_Host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('rootserver.domain.com', port=22, username='admin', password='adminpass')
stdin, stdout, stderr = ssh.exec_command('/bin/su root -c "smartctl -a /dev/sda > /tmp/smartctl_output"', get_pty=True)
stdin.write('rootpass\n')
stdin.flush()
print (stdout.readlines())
ssh.close()
これは、bashで次のように簡単に実行できます。suとの人間の相互作用をシミュレートします。 Sudoを搭載していないサーバーの自動リモートインストーラーで使用します。
sucmd="sh -c 'sleep 3; echo $pass' | script -qc 'su -c ./yourscript.sh root '"
ssh -t -l "$user" "$ipaddress" -p 22 "$sucmd"
敬具、