
我從這個完全有效的 ssh 命令開始:
$ ssh -fNL 3306:localhost:3306 [email protected]
這個配置讓我得到了我所追求的部分簡化:
Host tunnel
HostName database.example.com
IdentityFile ~/.ssh/coolio.example.key
LocalForward 3306 localhost:3306
User coolio
我可以用這個命令連接,這要好得多:
$ ssh -f -N tunnel
我現在的問題是如何對其進行參數化,以便我可以執行此操作(或類似操作):
$ ssh -f -N tunnel -p 3306
或者:
$ ssh -f -N tunnel -p 5678
順便說一句,在我上面的範例中,我故意在兩個地方使用相同的連接埠號碼。這就是我在這種情況下所需要的。 (但我也想知道如果端口不同,如何對其進行參數化。)
到目前為止我嘗試過的:
Host tunnel
HostName database.example.com
IdentityFile ~/.ssh/coolio.example.key
LocalForward %p localhost:%p
User coolio
這給了錯誤:
ssh/config 錯誤的轉發規範
參考:
http://nerderati.com/2011/03/simplify-your-life-with-an-ssh-config-file/
答案1
這不是最優雅的方式,但我會這樣做:
將原始文件中的連接埠規範替換為唯一的模式。例如:
LocalForward myport localhost:myport
ssh
來自您的別名.bashrc
:alias ssh='/path/to/ssh_wrapper.pl'
寫入檔案
/path/to/ssh_wrapper.pl
:#!/usr/bin/perl use strict; use warnings; my $cmdline = join ' ',@ARGV; if($cmdline =~ / -p\s*([0-9]+)\b/ and $cmdline=~ / -N/){ my $port = $1; system("sed 's/myport/$port/g' /etc/ssh/ssh_config > /tmp/ssh_config"); } else{ system("sed 's/LocalForward/#LocalForward/' /etc/ssh/ssh_config > /tmp/ssh_config"); } $cmdline .= ' -F /tmp/ssh_config'; my $pid = fork; $pid ? wait : exec("/usr/bin/ssh $cmdline"); unlink '/tmp/ssh_config';
基本上,這將解析您的
ssh
命令行,如果它找到一個-p
後跟數字端口規範的選項,它將通過用您在命令行上指定的數字端口值替換每個出現的位置來創建一個新ssh_config
選項。之後,它-使用命令行對真實的系統調用。如果它創建了自己的配置文件,它會在命令列中添加一個選項,以確保從新創建的配置文件中讀取。最後,父進程讓fork 完成,然後刪除臨時設定檔。/tmp/ssh_config
myport
fork
exec
ssh
-F
ssh
wait
ssh
ssh
免責聲明
該代碼未經測試。嘗試需要您自擔風險。首先備份您的設定檔!
編輯
當您不通過提供數字端口時,前面編寫的程式碼將因“錯誤的連接埠規範”錯誤而中斷,-p
因此我添加了程式碼來註釋該LocalForward
部分,以防不需要它。我還確保設定檔中的替換不會發生,除非還有一個-N
選項,因為您可能想要指定一個連接埠-p
而不需要轉送(例如ssh
進入使用非標準連接埠的盒子)。
答案2
我解決這個問題的一個更簡單的方法是在我的 .bashrc 中建立一個函數
sshfw () {
ssh -fNL "$1":localhost:"$1" "$2"
}
現在我可以做
sshfw 8890 [email protected]