คุณสามารถตั้งรหัสผ่านเป็น. ssh / config เพื่ออนุญาตการเข้าสู่ระบบอัตโนมัติได้หรือไม่


93

ฉันใช้ Ubuntu 11.10 ฉันใช้sshสำหรับเชื่อมต่อกับเซิร์ฟเวอร์หลาย ๆ ตัวต่อวันดังนั้นฉันจึงใส่พารามิเตอร์ไว้ใน.ssh/configไฟล์ดังนี้

Host Home
User netmoon
Port 22
HostName test.com

มีวิธีการใส่รหัสผ่านสำหรับแต่ละการเชื่อมต่อในไฟล์นี้ดังนั้นเมื่อเซิร์ฟเวอร์ขอรหัสผ่านเทอร์มินัลจะป้อนรหัสผ่านและส่งไปยังเซิร์ฟเวอร์หรือไม่

ฉันต้องการเพราะบางครั้งผมยืนอยู่ห่างออกไปจากเครื่องคอมพิวเตอร์และเมื่อฉันกลับไปพิมพ์รหัสผ่านและกดขั้วกล่าวว่าEnterCONNECTION CLOSED

ป.ล. ฉันไม่ต้องการใช้คู่คีย์สาธารณะ / ส่วนตัว


1
ฉันอยู่ในสถานการณ์เดียวกันและฉันไม่สามารถอัพโหลดกุญแจสาธารณะของฉันได้เพราะฉันมีสิทธิ์เข้าถึง ssh สำหรับ svn เท่านั้น นั่นคือถ้าฉันลอง ssh svnhost ฉันจะได้รับ "(สำเร็จ (2 2 ()) (แก้ไขไปป์ไลน์ svndiff1 รายการที่ไม่ปรากฏคอมมิทคอม - ล็อก - ลึก - รีเพลย์ -) -) การตอบสนอง svnserve ไม่ใช่เชลล์
Uberto

ดูunix.stackexchange.com/a/83991/26493และandre.frimberger.de/index.php/linux/...SSH_ASKPASSหาวิธีการโดยใช้
Olaf Dietsche

คำตอบ:


56

ซื้อขายปิดการรักษาความปลอดภัยเพื่อความสะดวกไม่สิ้นสุด ...

คุณสามารถใช้ssh-copy-idจากopenssh-clientแพ็คเกจได้หรือไม่?

จากman ssh-copy-id:

ssh-copy-id เป็นสคริปต์ที่ใช้ ssh เพื่อเข้าสู่เครื่องระยะไกลและผนวกไฟล์ข้อมูลประจำตัวที่ระบุไปยังไฟล์ ~ / .ssh / authorized_keys ของเครื่องนั้น


12
สิ่งนี้จะไม่ทำงานหากผู้ดูแลระบบระยะไกลยืนยันว่าจะปิดใช้งานการอนุญาตพับลิกคีย์ ...
tomasz

2
ใช่ แต่การเป็นจริงในระบบภายใต้การกำกับดูแลโดยตรงและการควบคุมทั้งหมดของคุณไม่ได้ทำให้เกิดความเสียหาย ตัวอย่างเช่นพูดบนเครื่องเสมือนจริงที่ไม่มีคนรู้จักใช้การเชื่อมต่อภายนอกเพื่อการพัฒนาในที่นั่งเดียว
สกอตต์

36
การยืนยันความปลอดภัยของ draconian ที่ไม่มีสาเหตุก็ไม่สิ้นสุดเช่นกัน
cwallenpoole

6
บางครั้งมันก็จบลงด้วยดี
devth

3
IMHO การยืนยันรหัสผ่านสำหรับการรับรองความถูกต้องมีความเสี่ยงมากกว่าไม่ บ่อยครั้งที่ฉันตั้งค่าให้ใช้รหัสผ่านสำหรับ ssh เป็นตัวแปรสภาพแวดล้อมในขณะที่ฉันลังเลที่จะจำชุดของสตริงโดยพลการ ด้วยการเรียกร้องให้ผู้ใช้ป้อนพวกเขาก็แค่ขอให้พวกเขาจัดเก็บไม่ดี
eggmatters

26

หากคุณไม่ต้องการใช้คู่คีย์สาธารณะ / ส่วนตัวคุณสามารถเขียนexpectสคริปต์เพื่อป้อนรหัสผ่านให้คุณโดยอัตโนมัติขึ้นอยู่กับที่อยู่ปลายทาง

แก้ไข: สิ่งที่ฉันหมายถึงคือคุณสามารถมีสคริปต์ที่ใช้expectในการป้อนรหัสผ่านสำหรับคุณและในอีกทางหนึ่งให้อ่านรหัสผ่านสำหรับผู้ใช้และโฮสต์ที่กำหนดจากไฟล์กำหนดค่า ตัวอย่างเช่นสคริปต์ python ต่อไปนี้จะทำงานกับสถานการณ์ในวันแดดจัด:

#!/usr/bin/python                                                                                                                        
import argparse
from ConfigParser import ConfigParser
import pexpect

def main(args):
    url = args.url
    user, host = url.split('@', 1)

    cfg_file = 'ssh.cfg'
    cfg = ConfigParser()
    cfg.read(cfg_file)
    passwd = cfg.get(user, host)

    child = pexpect.spawn('ssh {0}'.format(url))
    child.expect('password:')
    child.sendline(passwd)
    child.interact()

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Run ssh through pexpect')
    parser.add_argument('url')
    args = parser.parse_args()
    main(args)

และรูปแบบไฟล์การกำหนดค่าจะเป็นดังนี้:

[user_1]
host1 = passwd_1
host2 = passwd_2

[user_2]
host1 = passwd_1
host2 = passwd_2

หมายเหตุ: ตามที่อธิบายไว้สคริปต์ python จะต้องมีความซับซ้อนมากขึ้นในการจัดการข้อผิดพลาดและข้อความคำถามจาก ssh และ URL ที่เป็นไปได้ทั้งหมด (ในตัวอย่างจะถือว่ามันเป็นสิ่งที่ต้องการuser@hostแต่ส่วนผู้ใช้ไม่ได้ ' ไม่ใช้เวลาส่วนใหญ่) แต่ความคิดพื้นฐานยังคงเหมือนเดิม เกี่ยวกับไฟล์กำหนดค่าคุณอาจใช้ไฟล์กำหนดค่าอื่นหรือใช้.ssh/configและเขียนรหัสของคุณเองเพื่อวิเคราะห์ไฟล์นั้นและรับรหัสผ่านสำหรับผู้ใช้และโฮสต์ที่กำหนด


คุณอธิบายเพิ่มเติมได้ไหม
Netmoon

@ Netmoon ฉันได้เพิ่มตัวอย่างเล็ก ๆ เพื่อตอบคำถามของฉันให้ชัดเจนยิ่งขึ้น
jcollado

สิ่งนี้ไม่ได้ตอบคำถามว่าจะใส่รหัสผ่านในไฟล์. ssh / config ได้อย่างไร
Eric Woodruff

1
แน่นอนมันไม่ได้ตอบคำถามนั้น แต่มันแก้ปัญหา: หลีกเลี่ยงการพิมพ์รหัสผ่านด้วยตนเองและเก็บไว้ในไฟล์ ซึ่งเป็นสิ่งที่ OP ต้องการ
Arcesilas

19

นอกจากนี้ยังมีsshpassโปรแกรมสำหรับการที่ วิธีใช้: sshpass -p MyPa55word ssh me@myservor.com


29
นอกจากว่าคุณจะนำหน้าคำสั่งด้วยช่องว่าง ( sshpassแทนsshpass) คุณเพิ่งเก็บรหัสผ่านของคุณ ("MyPa55word") ไว้ในไฟล์ประวัติของเชลล์
waltinator

1
@waltinator จุดดี
igor

3
ถ้าผู้ถามคำถามถูกกับมันอยู่.ssh/configทำไมไม่อยู่ในประวัติเชลล์ด้วย?
Darth Egregious

มันไม่ได้เป็นอย่างเป็นทางการเมื่อ Homebrew แต่คุณสามารถติดตั้งจาก repo brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rbของบุคคลที่สามด้วย เพิ่มเติมได้ที่: gist.github.com/arunoda/7790979
จาค็อบฟอร์ด

read -s password; sshpass -p "$password" ssh me@myservor.com. วิธีนี้จะป้องกันไม่ให้แสดงรหัสผ่านในประวัติศาสตร์
อเล็กซานเดอร์เบิร์ด

19

วิธีการเกี่ยวกับ ProxyCommand:

Host Home-raw
    HostName test.com
Host Home
   User netmoon
   Port 22
   ProxyCommand sshpass -pmypass ssh netmoon@%h-raw nc localhost %p

คุณสามารถใช้ssh -Wแทนncเช่นกัน:

ProxyCommand sshpass -pmypass ssh netmoon@%h-raw -W localhost:%p

มันจะไม่ทำงานตามที่คาดไว้ด้วย-Wตัวเลือก คุณมีวิธีแก้ปัญหาหรือไม่?
Toan Nguyen

2
มันยังคงถามรหัสผ่านด้วยคำสั่งพร็อกซีนี้ ...
Victor Piousbox

1
ฉันยังพบว่ามันยังขอรหัสผ่าน ทั้งหมดนี้ดูเหมือนจะทำคือย้ายปัญหาจากการtest.comกำหนดรหัสผ่านเพื่อHomeกำหนดรหัสผ่าน ประเด็นคืออะไร? เคล็ดลับในการทำให้มันทำงานคืออะไร?
Martin Bramwell

15

ไม่ได้นี่เป็นไปไม่ได้ที่ฉันกลัว

ทางเลือกเดียวที่แท้จริงคือการใช้กุญแจส่วนตัว แต่คุณบอกว่าคุณไม่ต้องการ (เพราะเหตุใด)


7
เพราะฉันไม่ได้รับอนุญาตให้ใส่รหัสอื่นบนเซิร์ฟเวอร์
Netmoon

2
@Netmoon: หากคุณสามารถเข้าสู่ระบบคุณสามารถเพิ่มรหัสใช่มั้ย? คุณต้องเขียนเพื่อเข้าถึงโฮมไดเร็กตอรี่ของคุณ, ยกเว้นว่าระบบดูแลระบบจะตั้งค่าแปลก ๆ
Scott Severance

4
@ScottSeverance ฉันคิดว่านั่นเป็นสถานการณ์ที่คำถามนี้อ้างถึง ไม่มีความสามารถในการเพิ่มคีย์ ใช่มันแปลก แต่ก็มักจะเกิดขึ้น
user239558

5
ฉันเคยมีประสบการณ์ทั่วไปเกี่ยวกับสภาพแวดล้อมการโฮสต์ที่ใช้ร่วมกันซึ่งการเข้าถึงพับลิกคีย์ถูกปิดใช้งานดังนั้นแม้ว่าคุณสามารถเพิ่มคีย์ได้ แต่ก็ไม่ได้ใช้ มันขัดแย้งกับเหตุผลที่ใช่ แต่นั่นเป็นวิธีที่ผู้ให้บริการโฮสติ้งจำนวนมากตั้งค่าเซิร์ฟเวอร์ของพวกเขา
billynoah

1
มีคำตอบที่แสดงว่าเป็นไปได้
Eric Woodruff

8

คุณสามารถสร้างสคริปต์ ssh แบบง่าย ๆ ได้ใน / usr / local / bin:

#!/bin/bash

host=$1
password=`awk "/#Password/ && inhost { print \\\$2 } /Host/ { inhost=0 } /Host $host/ { inhost=1 }" ~/.ssh/config`

if [[ -z "$password" ]]; then
  /usr/bin/ssh $*
else
  sshpass -p $password /usr/bin/ssh $*
fi

จากนั้นในไฟล์ ~ / .ssh / config ของคุณคุณสามารถใช้

Host foohost
    User baruser
    #Password foobarpassword

4

ผมใช้โปรแกรมจาก VanDyke ซอฟท์แวเรียกSecureCRT

http://www.vandyke.com/products/securecrt/

มันไม่ฟรี แต่ราคาสมเหตุสมผลมาก ฉันใช้มาหลายปีแล้ว (ใช้งานบน Windows หรือใช้ Wine) สำหรับการเข้าถึงระยะไกลการจำลองเทอร์มินัลและการจัดการเครือข่าย (แยกย้ายกัน) ในที่สุดพวกเขาก็เปิดตัว Linux เวอร์ชันดั้งเดิมในต้นปี 2554

มันมีการสนับสนุนสำหรับการตั้งค่าการเข้าสู่ระบบที่ซับซ้อน (หรือสคริปต์) รหัสผ่านที่เก็บไว้ (หรือใบรับรอง) แท็บหลายเซสชัน ฯลฯ

เมื่อเริ่มต้นคุณสามารถเลือกเป้าหมายระยะไกล (และโปรโตคอล) จากรายการโครงสร้าง (มุมมองแบบต้นไม้) ของเครื่องระยะไกล (หรือภายในเครื่อง) ที่เก็บไว้หรือเพียงแค่สร้างการเชื่อมต่อ (ซึ่งจะถูกเก็บไว้)

ฉันพบว่ามีประโยชน์อย่างยิ่งสำหรับไซต์ระยะไกลที่มีการรับรองความถูกต้องขั้นสูงพอร์ตที่ไม่ได้มาตรฐานหรือการเจรจาต่อรองการเข้าถึงไฟร์วอลล์

หากคุณทำการเข้าถึงระยะไกลเป็นจำนวนมาก (เป็นส่วนหนึ่งของบทบาทหลักของคุณ) แอปพลิเคชันนี้จะปรับค่าใช้จ่ายในเดือนแรกของการใช้งาน


ขอโทษฉันไม่เข้าใจ คุณสามารถอธิบาย ?
Netmoon

1
reworded สำหรับคุณ ..
david6

2
นับตั้งแต่การโพสต์คำตอบข้างต้นมีการทำซ้ำของ SecureCRT รวมถึง VanDyke ตัวล่าสุดที่เพิ่งเปิดตัวเมื่อต้นเดือนธันวาคม 2556 การทำซ้ำแต่ละครั้งได้รับการปรับปรุงโปรแกรมทำให้มีความหลากหลายมากยิ่งขึ้น นอกจากนี้ยังมี rich API ที่อนุญาตให้โปรแกรมสามารถควบคุม / เชื่อมต่อกับสคริปต์ Python / VB SecureCRT เป็นส่วนหนึ่งของชุดเครื่องมือหลักของฉันมาสิบปีแล้วและฉันขอแนะนำ
วิลล์

ตกลง ผมก็ยังคงเบต้าทดสอบแต่ละรุ่นใหม่และผู้ที่เกี่ยวข้องอย่างมากในการทดสอบก่อนสำหรับการย้ายไปอูบุนตู
david6

2

ตอบคำถามที่คุณถามไม่สามารถกำหนดรหัสผ่านเริ่มต้นในไฟล์กำหนดค่า ssh ได้

แต่ถ้าอย่างที่คุณพูดมันเป็น"เพราะบางครั้งฉันยืนห่างจากพีซีและเมื่อฉันกลับไปพิมพ์รหัสผ่านและกดEnterterminal บอกว่าCONNECTION CLOSED"แล้วทำไมไม่ป้องกันการปิดเซสชันแทน? SSH สามารถทำให้การเชื่อมต่อมีชีวิตชีวาสำหรับคุณ

Host Home
  User netmoon
  Port 22
  HostName test.com
  ServerAliveInterval 300
  ServerAliveCountMax 2

1

ขอบคุณ Arek สำหรับแรงบันดาลใจ ...

แทนที่จะเรียกใช้กระบวนการเชลล์อื่นนี่เป็นเพียงฟังก์ชั่นที่ทำงานในเชลล์ bash ปัจจุบัน มันรันawkคำสั่งเดียวในการแยกวิเคราะห์ไฟล์ config และคิดออกว่าควรใช้รหัสผ่านจากตัวแปรเชลล์หรือจากรหัสผ่านที่เขียนเป็นรหัส cleartext ลงในไฟล์ config ssh ( awkในevalแทนที่จะเป็นdescribeเพราะปัญหาที่ฉันกดใช้describe)

ฉันลองใช้หลายวิธีsshpassโดยตรงในsshไฟล์ปรับแต่งโดยใช้ ProxyCommand แต่ดูเหมือนว่าจะไม่มีอะไรทำงานได้อย่างที่คาดไว้ยกเว้นเมื่อฉันสามารถเข้าสู่กล่องผ่านทาง RSA ได้ แต่ฉันต้องส่งรหัสผ่านเพื่อเปิดไดเรกทอรีที่เข้ารหัสของฉัน อย่างไรก็ตามฟังก์ชั่นของฉันด้านล่างดูเหมือนจะทำงานให้ฉันในทุกกรณีแม้สำหรับ Cygwin

# In your .bash_profile
function ssh(){
    host=$1;
    unset PASSWORD
    unset PASSVAR
    eval $(awk "/ *#[Pp]assvar / && inhost { printf \"PASSVAR=%s\",\$2; exit 1 } / *#[Pp]assword / && inhost { printf \"PASSWORD=%s\",\$2; } /^#?[Hh][oO][sS][tT] / && inhost { inhost=0; exit 1 } /^[Hh][oO][sS][tT] $host\$/ { inhost=1 }" ~/.ssh/config)
    if [[ -z "$PASSWORD" ]] && [[ -z "$PASSVAR" ]]; then
        /usr/bin/ssh -q $* 2>/dev/null
    else
       if [[ -n "$PASSVAR" ]]; then
          PASSWORD=$(TMP=${!PASSVAR-*};echo ${TMP##*-})
       fi
       /usr/local/bin/sshpass -p"$PASSWORD" /usr/bin/ssh -q $* 2>/dev/null
    fi
}
# and setup your passwords (perhaps in .bashrc instead...)
MYPASS_ENVVAR=SomePassword
MYPASSWD_FROM_FILE=$(</home/me/.passwd_in_file)

จากนั้น~/.ssh/configส่วนจะมีลักษณะดังนี้:

Host MyHostname
 Port 22
 Hostname 2.1.2.2
 User merrydan
 #Passvar MYPASS_ENVVAR
 #Password Some!Password

ถ้า มีอยู่ในส่วนของการตั้งค่านี้จะแทนที่#Passvar เป็นตัวแปรสภาพแวดล้อมที่ถือรหัสผ่านของคุณ#Password
$MYPASS_ENVVAR

สนุก!


1

คำตอบของ @BrunoPereira สำหรับคำถามนี้แสดงวิธีการอื่นในการเชื่อมต่อโดยไม่ต้องป้อนรหัสผ่านอย่างชัดเจนและหลีกเลี่ยงการใช้คีย์ ssh

คุณสามารถสร้างสคริปต์นามแฝงหรือฟังก์ชันใน~/.bashrcการดำเนินการคำสั่งนั้นได้อย่างรวดเร็ว

เห็นได้ชัดว่ามีข้อควรพิจารณาด้านความปลอดภัยที่คุณควรคำนึงถึงด้วยวิธีการนี้


เป็นเรื่องดีที่คุณเชื่อมโยงไปยังโซลูชัน - แต่ก็เป็นแนวปฏิบัติที่ดีที่จะดำเนินการต่อและโพสต์โซลูชันที่นี่ ด้วยวิธีนี้หากลิงก์ถูกลบออก (เช่นเคยเกิดขึ้นกับการแลกเปลี่ยนสแต็กเป็นครั้งคราว) ยังมีคำตอบที่ใช้งานได้ที่นี่
พอล

0

นี่คือรูปแบบที่ซับซ้อนของฉันในคำตอบของ @ ArekBurdach มันมีนามสกุลต่อไปนี้:

  • โฮสต์สามารถเป็นที่ใดก็ได้ในsshบรรทัดคำสั่ง; เช่นมันยังสนับสนุนssh <args> <host> <commands>ไวยากรณ์
  • ไม่ฮาร์ดโค้ดพา ธ ไปที่ ssh
  • การแยกวิเคราะห์ที่มีประสิทธิภาพมากขึ้น ssh_config
  • โบนัส: เสื้อคลุมสำหรับscpเกินไป

ssh-wrapper

#!/bin/bash

password=$(awk '
BEGIN {
    # Collect the SSH arguments as keys of a dictionary, so that we can easily
    # check for inclusion.
    for (i = 2; i < ARGC; i++) {
        sshArgs[ARGV[i]] = 1
    }

    # Only process the first argument; all others are the command-line arguments
    # given to ssh.
    ARGC = 2
}
$1 == "Password" && inhost { print $2 }
/^\s*Host\s/ {
    if ($2 in sshArgs)
        inhost=1
    else
        inhost=0
}
' ~/.ssh/config "$@")


if [ "$password" ]; then
    sshpass -p "$password" "$(which ssh)" "$@"
else
    "$(which ssh)" "$@"
fi

scp-wrapper

#!/bin/bash

password=$(awk '
BEGIN {
    # Collect the SCP arguments as keys of a dictionary, so that we can easily
    # check for inclusion.
    for (i = 2; i < ARGC; i++) {
        colonIdx = index(ARGV[i], ":")
        if (colonIdx > 0) {
            scpArgs[substr(ARGV[i], 1, colonIdx - 1)] = 1
        }
    }

    # Only process the first argument; all others are the command-line arguments
    # given to scp.
    ARGC = 2
}
$1 == "Password" && inhost { print $2 }
/^\s*Host\s/ {
    if ($2 in scpArgs)
        inhost=1
    else
        inhost=0
}
' ~/.ssh/config "$@")


if [ "$password" ]; then
    sshpass -p "$password" "$(which scp)" "$@"
else
    "$(which scp)" "$@"
fi

การติดตั้ง

กำหนดนามแฝงใน~/.bashrc:

alias ssh=ssh-wrapper
alias scp=scp-wrapper

องค์ประกอบ

ด้วยIgnoreUnknownคำสั่งsshอย่าบ่นเกี่ยวกับPasswordคำสั่งที่เพิ่งเปิดตัวดังนั้น (ตรงกันข้ามกับคำตอบของ @ ArekBurdach) เราสามารถทำให้สิ่งนี้ปรากฏเป็นรูปแบบ "ของจริง" หากคุณไม่ชอบสิ่งนี้ก็เป็นการง่ายที่จะเปลี่ยนสคริปต์กลับเป็นสคริปต์ที่แสดงความคิดเห็น

# Allow specifying passwords for Host entries, to be parsed by ssh-wrapper.
IgnoreUnknown Password

Host foohost
    User baruser
    Password foobarpassword

0

หากคุณไม่สามารถเข้าถึงคู่คีย์ได้โดยตรงคุณสามารถเข้ารหัสรหัสผ่านบนเครื่องท้องถิ่นของคุณ

วิธีที่จะทำคือเข้ารหัสรหัสผ่านของคุณโดยใช้คีย์นอกจาก ProxyCommand ของ @Eric Woodruff

วิธีการรวมคือการใช้ท่อ:

openssl rsautl -decrypt -inkey /path/to/decrypt_key -in /path/to/encrypted_password  | sshpass ssh real-destination -tt

ที่ไหน

Host real-destination
    Hostname test.com
    User netmoon

0

มีความแตกต่างเล็กน้อยจากวิธีการที่อธิบายไว้ในบล็อกเกี่ยวกับวิธีการใช้คือsshpass ซึ่งสามารถพบได้ที่นี่ ระบุว่าคุณมีไฟล์รหัสผ่านที่เข้ารหัส gpg (อธิบายวิธีการทำสิ่งนี้ในบล็อก) ไฟล์ที่คุณสามารถทำสิ่งนี้:

 sshpass -p $(echo $(gpg -d -q .sshpasswd.gpg)) ssh your_desination.xyz

.bashrcและเพียงบันทึกคำสั่งที่เป็นชื่อแทนในของคุณ

หากคุณต้องการเชื่อมต่อผ่านการเชื่อมต่อนั้นคุณสามารถทำอะไรได้บ้าง

 Host actual_dest
      Hostname actual.dest.xyz
      User username
      ProxyCommand sshpass -p $(echo $(gpg -d -q ~/.sshpasswd.gpg)) \ 
                   ssh your_destination.xyz nc %h %p
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.