Skip to content
Update ssh authored by umaumax's avatar umaumax
[[_TOC_]] [[_TOC_]]
## 設定ファイル ## 設定ファイル
### `~/.ssh/config` ### `~/.ssh/config`
#### ProxyJump #### ProxyJump
[多段SSHならProxyJump!さよならProxyCommand | にっしーラボ]( https://nissy-lab.com/blogs/multiple-ssh-proxyjump/ ) [多段SSHならProxyJump!さよならProxyCommand | にっしーラボ]( https://nissy-lab.com/blogs/multiple-ssh-proxyjump/ )
#### sshの接続先の名称で処理を振り分けたい #### sshの接続先の名称で処理を振り分けたい
[SSHのDynamic Forwardを気軽に使うTIPS \| Zenn]( https://zenn.dev/hnw/articles/36e70c0980c8786c7154 ) [SSHのDynamic Forwardを気軽に使うTIPS \| Zenn]( https://zenn.dev/hnw/articles/36e70c0980c8786c7154 )
#### [sshをproxy経由でつなぐ \- @znz blog]( https://blog.n-z.jp/blog/2018-08-12-ssh-over-proxy.html ) #### [sshをproxy経由でつなぐ \- @znz blog]( https://blog.n-z.jp/blog/2018-08-12-ssh-over-proxy.html )
``` bash ``` bash
sudo apt-get install -y connect-proxy sudo apt-get install -y connect-proxy
``` ```
``` conf ``` conf
Host github github.com Host github github.com
HostName github.com HostName github.com
User git User git
IdentityFile ~/.ssh/XXX_id_rsa IdentityFile ~/.ssh/XXX_id_rsa
ProxyCommand connect -H proxy-XXX.com:10080 %h %p ProxyCommand connect -H proxy-XXX.com:10080 %h %p
``` ```
#### sshのpublic key #### sshのpublic key
`~/.ssh/config``IdentityFile`のファイル名+`.pub`のファイルの形式が不正の場合 `~/.ssh/config``IdentityFile`のファイル名+`.pub`のファイルの形式が不正の場合
``` ```
key_load_public: invalid format key_load_public: invalid format
``` ```
というメッセージが表示される というメッセージが表示される
ファイル形式が、一見、正しくとも、`~/.ssh/authorized_keys`のように複数のpublic keyが登録されている場合(他のサーバの`authorized_keys`を流用している場合)に、 ファイル形式が、一見、正しくとも、`~/.ssh/authorized_keys`のように複数のpublic keyが登録されている場合(他のサーバの`authorized_keys`を流用している場合)に、
なぜか秘密鍵を利用したsshアクセスができなくなっている なぜか秘密鍵を利用したsshアクセスができなくなっている
おそらく、サーバからではなく、localのpublic keyの先頭行と比較して弾いている? おそらく、サーバからではなく、localのpublic keyの先頭行と比較して弾いている?
### `~/.ssh/known_hosts` ### `~/.ssh/known_hosts`
defaultでhash化されているので、下記を`~/.ssh/config`へ適用するとhash化されなくなる defaultでhash化されているので、下記を`~/.ssh/config`へ適用するとhash化されなくなる
``` ```
Host * Host *
HashKnownHosts no HashKnownHosts no
``` ```
* [SSHのホスト鍵設定 \- 簡潔なQ]( https://qnighy.hatenablog.com/entry/2017/10/29/220000 ) * [SSHのホスト鍵設定 \- 簡潔なQ]( https://qnighy.hatenablog.com/entry/2017/10/29/220000 )
* [github の IP アドレスをまとめて known\_hosts に登録する — KaoriYa]( https://www.kaoriya.net/blog/2016/07/04/ ) * [github の IP アドレスをまとめて known\_hosts に登録する — KaoriYa]( https://www.kaoriya.net/blog/2016/07/04/ )
* hash化しないようにすれば,上記のページの通り,`github.com`のすべてのIPアドレスを一括で登録できるようになる * hash化しないようにすれば,上記のページの通り,`github.com`のすべてのIPアドレスを一括で登録できるようになる
### sshd(/etc/ssh/sshd_config) ### sshd(/etc/ssh/sshd_config)
#### デフォルト値 #### デフォルト値
`man sshd_config` [sshd\_config\(5\)]( https://www.freebsd.org/cgi/man.cgi?sshd_config(5) ) `man sshd_config` [sshd\_config\(5\)]( https://www.freebsd.org/cgi/man.cgi?sshd_config(5) )
#### 設定ファイルの文法チェック #### 設定ファイルの文法チェック
``` bash ``` bash
sshd -t sshd -t
``` ```
## rootユーザへパスワード入力無しでログイン(鍵不使用) ## rootユーザへパスワード入力無しでログイン(鍵不使用)
[linux \- How do I completely remove root password \- Stack Overflow]( https://stackoverflow.com/questions/11700690/how-do-i-completely-remove-root-password ) [linux \- How do I completely remove root password \- Stack Overflow]( https://stackoverflow.com/questions/11700690/how-do-i-completely-remove-root-password )
1. rootのパスワードをなしにする 1. rootのパスワードをなしにする
`passwd -d root` `passwd -d root`
具体的には`/etc/shadow``root`の行の2番目の項目が空白になっていればOK 具体的には`/etc/shadow``root`の行の2番目の項目が空白になっていればOK
`sed -i 's/^root:[^:]\+:/root::/' /etc/shadow` `sed -i 's/^root:[^:]\+:/root::/' /etc/shadow`
2. sshdの設定でパスワードなしログインを許可する 2. sshdの設定でパスワードなしログインを許可する
`/etc/ssh/cat sshd_config` `/etc/ssh/cat sshd_config`
``` ```
PasswordAuthentication yes # default: yes PasswordAuthentication yes # default: yes
PermitRootLogin yes # default: yes PermitRootLogin yes # default: yes
PermitEmptyPasswords yes # default: no PermitEmptyPasswords yes # default: no
UsePAM no # default: no UsePAM no # default: no
``` ```
各デフォルト設定: [sshd\_config\(5\)]( https://www.freebsd.org/cgi/man.cgi?sshd_config(5) ) 各デフォルト設定: [sshd\_config\(5\)]( https://www.freebsd.org/cgi/man.cgi?sshd_config(5) )
`sudo service sshd restart`で再起動する `sudo service sshd restart`で再起動する
## ssh中にhang upした場合の対処法 ## ssh中にhang upした場合の対処法
* [SSH Escape Sequences \- Today I Learned]( https://til.hashrocket.com/posts/d909a57428-ssh-escape-sequences ) * [SSH Escape Sequences \- Today I Learned]( https://til.hashrocket.com/posts/d909a57428-ssh-escape-sequences )
* [How can I break out of ssh when it locks? \- Ask Ubuntu]( https://askubuntu.com/questions/29942/how-can-i-break-out-of-ssh-when-it-locks ) * [How can I break out of ssh when it locks? \- Ask Ubuntu]( https://askubuntu.com/questions/29942/how-can-i-break-out-of-ssh-when-it-locks )
* [networking \- Why do consoles sometimes hang forever when SSH connection breaks? \- Server Fault]( https://serverfault.com/questions/283129/why-do-consoles-sometimes-hang-forever-when-ssh-connection-breaks ) * [networking \- Why do consoles sometimes hang forever when SSH connection breaks? \- Server Fault]( https://serverfault.com/questions/283129/why-do-consoles-sometimes-hang-forever-when-ssh-connection-breaks )
> There is a "secret" keyboard shortcut to force an exit :~) From the frozen session, hit these keys in order: Enter~. The tilde (only after a newline) is recognized as an escape sequence by the ssh client, and the period tells the client to terminate it's business without further ado. > There is a "secret" keyboard shortcut to force an exit :~) From the frozen session, hit these keys in order: Enter~. The tilde (only after a newline) is recognized as an escape sequence by the ssh client, and the period tells the client to terminate it's business without further ado.
例えば,2重でsshをしているときには,`<Enter>`, `~`, `~`, `.`を入力すればよい 例えば,2重でsshをしているときには,`<Enter>`, `~`, `~`, `.`を入力すればよい
(`~`の個数番目の`ssh`がcloseされる) (`~`の個数番目の`ssh`がcloseされる)
### [Debian/shutdownやrebootするとssh接続の端末がハングする \- Linuxと過ごす]( https://linux.just4fun.biz/?Debian/shutdown%E3%82%84reboot%E3%81%99%E3%82%8B%E3%81%A8ssh%E6%8E%A5%E7%B6%9A%E3%81%AE%E7%AB%AF%E6%9C%AB%E3%81%8C%E3%83%8F%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B ) ### [Debian/shutdownやrebootするとssh接続の端末がハングする \- Linuxと過ごす]( https://linux.just4fun.biz/?Debian/shutdown%E3%82%84reboot%E3%81%99%E3%82%8B%E3%81%A8ssh%E6%8E%A5%E7%B6%9A%E3%81%AE%E7%AB%AF%E6%9C%AB%E3%81%8C%E3%83%8F%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B )
サーバ側の設定でこの現象を防止することができるらしい サーバ側の設定でこの現象を防止することができるらしい
## ポートフォワーディング ## ポートフォワーディング
[sshポートフォワーディング \- Qiita]( https://qiita.com/mechamogera/items/b1bb9130273deb9426f5 ) [sshポートフォワーディング \- Qiita]( https://qiita.com/mechamogera/items/b1bb9130273deb9426f5 )
`-f`を指定するとbackgroundになり、わかりにくいので、単に、`-N`だけがおすすめ `-f`を指定するとbackgroundになり、わかりにくいので、単に、`-N`だけがおすすめ
フォワードする方向は片方向のみであることに注意 フォワードする方向は片方向のみであることに注意
### リモートフォワード(リモートからローカルの方向へつなぐ) ### リモートフォワード(リモートからローカルの方向へつなぐ)
`[local] -> [target] <-> [target2]` (矢印の方向にアクセス可能な環境を仮定) `[local] -> [target] <-> [target2]` (矢印の方向にアクセス可能な環境を仮定)
`ssh -N $TARGET -R 8080:localhost:10080` `ssh -N $TARGET -R 8080:localhost:10080`
としたとき としたとき
`$TARGET:8080`->`localhost:10080`の方向つながるが、`$TARGET`外から`$TARGET:8080`へのアクセスはできない `$TARGET:8080`->`localhost:10080`の方向つながるが、`$TARGET`外から`$TARGET:8080`へのアクセスはできない
`$TARGET`外からアクセスしたい場合は下記の3通り `$TARGET`外からアクセスしたい場合は下記の3通り
* A. $TARGET上で`ssh -N $TARGET2 -R 9090:localhost:8080`としてコネクションを追加で貼る必要がある * A. $TARGET上で`ssh -N $TARGET2 -R 9090:localhost:8080`としてコネクションを追加で貼る必要がある
* `$TARGET2:9090` -> `$TARGET:8080` -> `localhost:10080`となる * `$TARGET2:9090` -> `$TARGET:8080` -> `localhost:10080`となる
* B. `/etc/ssh/sshd_config``GatewayPorts yes`を追加する(`GatewayPorts`のデフォルト値は`no`) * B. `/etc/ssh/sshd_config``GatewayPorts yes`を追加する(`GatewayPorts`のデフォルト値は`no`)
* C. 単に`$TARGET`を経由させずに直接`ssh -N $TARGET2 -R 9090:localhost:10080` * C. 単に`$TARGET`を経由させずに直接`ssh -N $TARGET2 -R 9090:localhost:10080`
FROM_HOST -> HOST -> TO_HOSTの3wayのようなつなぎ方も可能 FROM_HOST -> HOST -> TO_HOSTの3wayのようなつなぎ方も可能
``` bash ``` bash
ssh -N $FROM_HOST -R $FROM_PORT:$TO_HOST:$TO_PORT ssh -N $FROM_HOST -R $FROM_PORT:$TO_HOST:$TO_PORT
``` ```
このとき、両方ともHOSTからsshできればOK(FROM_HOSTからTO_HOSTへssh接続するわけではない) このとき、両方ともHOSTからsshできればOK(FROM_HOSTからTO_HOSTへssh接続するわけではない)
### ローカルフォワード(ローカルからリモートの方向へつなぐ) ### ローカルフォワード(ローカルからリモートの方向へつなぐ)
ローカルフォワードのときは下記のオプションを付加すると簡単に指定できる ローカルフォワードのときは下記のオプションを付加すると簡単に指定できる
> -g Allows remote hosts to connect to local forwarded ports. If used on a multiplexed connection, then this option must be specified on the master process. > -g Allows remote hosts to connect to local forwarded ports. If used on a multiplexed connection, then this option must be specified on the master process.
`ssh -g -L 8080:$TARGET2:10080 $TARGET` `ssh -g -L 8080:$TARGET2:10080 $TARGET`
`localhost:8080` -> `$TARGET` -> `$TARGET2:10080`とつながる `localhost:8080` -> `$TARGET` -> `$TARGET2:10080`とつながる
> * -f: Requests ssh to go to background just before command execution. > * -f: Requests ssh to go to background just before command execution.
> * -N: Do not execute a remote command. This is useful for just forwarding ports. > * -N: Do not execute a remote command. This is useful for just forwarding ports.
`-g`なし `-g`なし
``` bash ``` bash
$ ss -atn $ ss -atn
LISTEN 0 128 ::1:8081 :::* LISTEN 0 128 ::1:8081 :::*
LISTEN 0 128 127.0.0.1:8081 *:* LISTEN 0 128 127.0.0.1:8081 *:*
``` ```
`-g`あり `-g`あり
``` bash ``` bash
$ ss -atn $ ss -atn
LISTEN 0 128 *:8081 *:* LISTEN 0 128 *:8081 *:*
LISTEN 0 128 :::8081 :::* LISTEN 0 128 :::8081 :::*
``` ```
### 簡単にポートフォワーディングしてアクセスしたい #### sshを利用しないローカルポートフォワーディング
よく利用するリモートターゲットの`~/.ssh/config`の接続先に下記のようにまとめて記述しておくと`localhost:xxx`としてアクセスできるので便利(多重に接続してもエラーなし) `ssh -N -L 28080:127.0.0.1:8080 localhost`相当の処理
``` ``` bash
LocalForward 10000 localhost:10000 python -m http.server 8080
LocalForward 10001 localhost:10001 curl localhost:28080
LocalForward 10002 localhost:10002
LocalForward 10003 localhost:10003 socat TCP4-LISTEN:28080,reuseaddr,fork TCP4:127.0.0.1:8080
LocalForward 10004 localhost:10004 ```
LocalForward 10005 localhost:10005
LocalForward 10006 localhost:10006 socatコマンドのバインド設定では外部からの通信も受け付けるようになっている
LocalForward 10007 localhost:10007 ``` bash
LocalForward 10008 localhost:10008 $ sudo lsof -i:28080
LocalForward 10009 localhost:10009 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
``` socat 75354 user 5u IPv4 0xc9257403876ca107 0t0 TCP *:28080 (LISTEN)
```
特に複数のリモートターゲットがある場合には便利
### 簡単にポートフォワーディングしてアクセスしたい
同様のことを実現したい場合にはvscodeのremote sshでリモートターゲットに接続していれば上記相当の処理が自動的に行われる よく利用するリモートターゲットの`~/.ssh/config`の接続先に下記のようにまとめて記述しておくと`localhost:xxx`としてアクセスできるので便利(多重に接続してもエラーなし)
### firewall機能によって、ローカルIPアドレスでのアクセスが禁止されているときの抜け穴の構築方法(ssh portfowarding利用) ```
LocalForward 10000 localhost:10000
``` LocalForward 10001 localhost:10001
# $FIREWALL_MACHINE: firewall機能で制限されているマシンで実行 LocalForward 10002 localhost:10002
ssh -N -R $PROXY_MACHINE 10080:localhost:80 LocalForward 10003 localhost:10003
LocalForward 10004 localhost:10004
# $PROXY_MACHINE: proxyとして利用する適当なマシンで実行する(これは上のremote portforwardingのポート(10080)が基本的にこのプロキシマシンのローカルに制限されるので、それを公開するためのコマンド) LocalForward 10005 localhost:10005
ssh -N -g -L 8080:localhost:10080 localhost LocalForward 10006 localhost:10006
``` LocalForward 10007 localhost:10007
LocalForward 10008 localhost:10008
`$PROXY_MACHINE:8080` => `$PROXY_MACHINE:10080` => `$FIREWALL_MACHINE:80`の方向でネットワークアクセスができる(これでwebsocketのport forwardingができることを確認済み) LocalForward 10009 localhost:10009
```
## `~/.ssh/config`なしの多段ProxyCommand利用時の注意
[ssh\_config\(5\) \- Linux manual page]( https://man7.org/linux/man-pages/man5/ssh_config.5.html#TOKENS ) 特に複数のリモートターゲットがある場合には便利
`%h`/`%p`などは多段化するときにはエスケープする必要がある(e.g. `%h:%p`, `%%h:%%p`, `%%%%h:%%%%p`) 同様のことを実現したい場合にはvscodeのremote sshでリモートターゲットに接続していれば上記相当の処理が自動的に行われる
``` bash ### firewall機能によって、ローカルIPアドレス(192.168.x.x)でのアクセスが禁止されているときの抜け穴の構築方法(ssh portfowarding利用)
ssh -oProxyCommand='ssh -W %h:%p -oProxyCommand="ssh -W %%h:%%p -oProxyCommand=\"ssh -W %%%%h:%%%%p HOST_A\" HOST_B" HOST_C' HOST_D hostname
``` ``` bash
# $FIREWALL_MACHINE: firewall機能で制限されているマシンで実行
正しいケース ssh -N -R $PROXY_MACHINE 10080:localhost:80
HOST_A -%%h:%%p-> HOST_B -%h:%p-> HOST_C # $PROXY_MACHINE: proxyとして利用する適当なマシンで実行する(これは上のremote portforwardingのポート(10080)が基本的にこのプロキシマシンのローカルに制限されるので、それを公開するためのコマンド)(これはsocatコマンドで代用可能である)
の順番で接続する ssh -N -g -L 8080:localhost:10080 localhost
``` bash ```
ssh -oProxyCommand='ssh -W %h:%p -oProxyCommand="ssh -W %%h:%%p HOST_A" HOST_B' HOST_C hostname
``` `$PROXY_MACHINE:8080` => `$PROXY_MACHINE:10080` => `$FIREWALL_MACHINE:80`の方向でネットワークアクセスができる(これでwebsocketのport forwardingができることを確認済み)
誤ったケース ## `~/.ssh/config`なしの多段ProxyCommand利用時の注意
[ssh\_config\(5\) \- Linux manual page]( https://man7.org/linux/man-pages/man5/ssh_config.5.html#TOKENS )
HOST_A -%h:%p-> HOST_Bで意図せずに接続されてしまうので、
`%h`/`%p`などは多段化するときにはエスケープする必要がある(e.g. `%h:%p`, `%%h:%%p`, `%%%%h:%%%%p`)
HOST_A -%h:%p-> HOST_Cとなる
``` bash ``` bash
ssh -oProxyCommand='ssh -W %h:%p -oProxyCommand="ssh -W %h:%p HOST_A" HOST_B' HOST_C hostname ssh -oProxyCommand='ssh -W %h:%p -oProxyCommand="ssh -W %%h:%%p -oProxyCommand=\"ssh -W %%%%h:%%%%p HOST_A\" HOST_B" HOST_C' HOST_D hostname
``` ```
## ダイナミックポートフォワード 正しいケース
ssh接続先をsocks proxyサーバとして利用する機能で,firefoxのプロキシ設定をsocksとすることで利用できる(curlならば`--socks5`オプションを利用する)
HOST_A -%%h:%%p-> HOST_B -%h:%p-> HOST_C
[ssh DynamicForwardでセキュアなssh接続 \- 自分用メモ]( https://hoshi-sbg.hatenablog.com/entry/2020/03/18/180234 ) の順番で接続する
``` bash
## Xをサポートしていない環境でクリップボードのコピーを行う ssh -oProxyCommand='ssh -W %h:%p -oProxyCommand="ssh -W %%h:%%p HOST_A" HOST_B' HOST_C hostname
[Forward your clipboard via SSH reverse tunnels]( https://gist.github.com/dergachev/8259104 ) ```
下記を`~/.ssh/config`に加える(単なる`Host *`では、例えば、git接続時にも適用されてしまうことに注意) 誤ったケース
``` HOST_A -%h:%p-> HOST_Bで意図せずに接続されてしまうので、
Host hoge*
RemoteForward 5556 localhost:5556 HOST_A -%h:%p-> HOST_Cとなる
``` ``` bash
ssh -oProxyCommand='ssh -W %h:%p -oProxyCommand="ssh -W %h:%p HOST_A" HOST_B' HOST_C hostname
下記のクリップボードサーバを動かす ```
``` bash
while true; do nc -l 5556 | xclip -sel clip; done ## ダイナミックポートフォワード
ssh接続先をsocks proxyサーバとして利用する機能で,firefoxのプロキシ設定をsocksとすることで利用できる(curlならば`--socks5`オプションを利用する)
# start clipboard daemon
if ! pgrep -f clipboard-daemon >/dev/null; then [ssh DynamicForwardでセキュアなssh接続 \- 自分用メモ]( https://hoshi-sbg.hatenablog.com/entry/2020/03/18/180234 )
nohup bash -c "exec -a clipboard-daemon bash -c 'while true; do { nc -d -l 5556 || sleep 1; } | xclip -sel clip; done'" >/dev/null 2>&1 &
fi ## Xをサポートしていない環境でクリップボードのコピーを行う
``` [Forward your clipboard via SSH reverse tunnels]( https://gist.github.com/dergachev/8259104 )
ssh先のサーバにて 下記を`~/.ssh/config`に加える(単なる`Host *`では、例えば、git接続時にも適用されてしまうことに注意)
``` bash
function c() { ```
# way 1 Host hoge*
# cat | nc -q0 localhost 5556 RemoteForward 5556 localhost:5556
# way 2 ```
# cat | telnet localhost 5556
# way 3 下記のクリップボードサーバを動かす
# bash -c 'cat > /dev/tcp/127.0.0.1/5556' ``` bash
while true; do nc -l 5556 | xclip -sel clip; done
# way 4
python3 <( # start clipboard daemon
cat <<EOF if ! pgrep -f clipboard-daemon >/dev/null; then
#!/usr/bin/env python3 nohup bash -c "exec -a clipboard-daemon bash -c 'while true; do { nc -d -l 5556 || sleep 1; } | xclip -sel clip; done'" >/dev/null 2>&1 &
import socket fi
import sys ```
import argparse
ssh先のサーバにて
``` bash
def main(): function c() {
parser = argparse.ArgumentParser( # way 1
formatter_class=argparse.ArgumentDefaultsHelpFormatter) # cat | nc -q0 localhost 5556
parser.add_argument('host', type=str) # way 2
parser.add_argument('port', type=int) # cat | telnet localhost 5556
# way 3
args, extra_args = parser.parse_known_args() # bash -c 'cat > /dev/tcp/127.0.0.1/5556'
data = sys.stdin.buffer.read() # way 4
python3 <(
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) cat <<EOF
client.connect((args.host, args.port)) #!/usr/bin/env python3
n = client.send(data) import socket
if n != len(data): import sys
print("failed to send data (data len = {}, send data len = {})".format(len(data), n), file=sys.stderr) import argparse
client.close()
def main():
parser = argparse.ArgumentParser(
if __name__ == '__main__': formatter_class=argparse.ArgumentDefaultsHelpFormatter)
main() parser.add_argument('host', type=str)
EOF parser.add_argument('port', type=int)
) localhost 5556
} args, extra_args = parser.parse_known_args()
```
data = sys.stdin.buffer.read()
## ssh先でterminal経由でファイルをコピー&ペーストしたい
* clipboardを利用する方法 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
* e.g. base64 client.connect((args.host, args.port))
* 長すぎると,terminalの挙動がとてつもなく重くなる(zshのpluginの影響であり,bashなら問題ない) n = client.send(data)
* 短い文字量ならば問題ない if n != len(data):
* tarコマンドを利用することで、実行権限付きでファイルをコピーでき、ディレクトリも対象にできる print("failed to send data (data len = {}, send data len = {})".format(len(data), n), file=sys.stderr)
* ネットワークを利用する方法(一時的なサーバを利用)
* ただし、サーバによっては自由にネットワークへ接続できないことに注意 client.close()
dotfilesに`pack`コマンドを作成した
if __name__ == '__main__':
## ssh rsa非推奨 main()
[SSH 公開鍵を ssh-rsa から強い暗号に書き換える - Qiita]( https://qiita.com/katzueno/items/4319fffc8b0b0b50d8a6 ) EOF
) localhost 5556
e.g. `ssh-keygen -t ecdsa -b 521` }
```
## tips
### [while内でsshを使うと1回で止まる \- Miuran Business Systems]( http://site.m-bsys.com/error/whileread-ssh ) ## ssh先でterminal経由でファイルをコピー&ペーストしたい
use `ssh -n` for avoid staling `stdin` (`-n Redirects stdin from /dev/null (actually, prevents reading from stdin). This must be used when ssh is run in the background.`) * clipboardを利用する方法
* e.g. base64
### [sshの鍵を作るときにちょっとだけ気にしたいこと \| Developers\.IO]( https://dev.classmethod.jp/articles/ssh-keygen-tips/ ) * 長すぎると,terminalの挙動がとてつもなく重くなる(zshのpluginの影響であり,bashなら問題ない)
`-C ""`を追記することで,hostnameが共通鍵にコメントとしてはいることを防止できる * 短い文字量ならば問題ない
* tarコマンドを利用することで、実行権限付きでファイルをコピーでき、ディレクトリも対象にできる
### ssh上でreboot * ネットワークを利用する方法(一時的なサーバを利用)
rebootの処理自体はsshが親プロセスでどうさするのではないため、セッションが切れても問題ないと考えられる * ただし、サーバによっては自由にネットワークへ接続できないことに注意
## トラブルシューティング dotfilesに`pack`コマンドを作成した
### 意図していない秘密鍵が利用される
`IdentitiesOnly` `yes`: IdentityFile で指定した秘密鍵でのみ認証を試みる設定を`~/.ssh/config`へ追加すると良い ## ssh rsa非推奨
[SSH 公開鍵を ssh-rsa から強い暗号に書き換える - Qiita]( https://qiita.com/katzueno/items/4319fffc8b0b0b50d8a6 )
デフォルト状態(`no`)に設定しておくと`ssh-add`で登録した秘密鍵も利用して認証を試みるので、基本的には`yes`にしておくほうが意図しない挙動とならない
e.g. `ssh-keygen -t ecdsa -b 521`
### ssh接続時に`Load key "/home/user/.ssh/hoge_id_rsa": error in libcrypto`というエラー
``` bash ## tips
Load key "/home/user/.ssh/hoge_id_rsa": error in libcrypto ### [while内でsshを使うと1回で止まる \- Miuran Business Systems]( http://site.m-bsys.com/error/whileread-ssh )
user@address: Permission denied (publickey,gssapi-keyex,gssapi-with-mic). use `ssh -n` for avoid staling `stdin` (`-n Redirects stdin from /dev/null (actually, prevents reading from stdin). This must be used when ssh is run in the background.`)
```
### [sshの鍵を作るときにちょっとだけ気にしたいこと \| Developers\.IO]( https://dev.classmethod.jp/articles/ssh-keygen-tips/ )
これは秘密鍵のファイルがおかしい場合(例えば、コピペミスで区切り文字のハイフンの個数が足りていないなど) `-C ""`を追記することで,hostnameが共通鍵にコメントとしてはいることを防止できる
``` bash ### ssh上でreboot
$ file bad_id_rsa rebootの処理自体はsshが親プロセスでどうさするのではないため、セッションが切れても問題ないと考えられる
bad_id_rsa: ASCII text
$ file good_id_rsa ## トラブルシューティング
good_id_rsa: PEM RSA private key ### 意図していない秘密鍵が利用される
``` `IdentitiesOnly` `yes`: IdentityFile で指定した秘密鍵でのみ認証を試みる設定を`~/.ssh/config`へ追加すると良い
なお、`bat`コマンドでも色がつくので違いがわかる
デフォルト状態(`no`)に設定しておくと`ssh-add`で登録した秘密鍵も利用して認証を試みるので、基本的には`yes`にしておくほうが意図しない挙動とならない
秘密鍵の正しい形式
``` ### ssh接続時に`Load key "/home/user/.ssh/hoge_id_rsa": error in libcrypto`というエラー
-----BEGIN RSA PRIVATE KEY----- ``` bash
...... Load key "/home/user/.ssh/hoge_id_rsa": error in libcrypto
-----END RSA PRIVATE KEY----- user@address: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
``` ```
### VSCodeのsshではgit情報を裏で処理しているための負荷が発生する これは秘密鍵のファイルがおかしい場合(例えば、コピペミスで区切り文字のハイフンの個数が足りていないなど)
[Visual Studio CodeでのSSH接続により、EC2サーバーが高負荷になり動かなくなった - エキサイト TechBlog.]( https://tech.excite.co.jp/entry/2022/09/27/153341 )
``` bash
### sshの接続が遅い $ file bad_id_rsa
認証鍵を利用する際にDNSアクセスがあるため、DNSの指定がおかしいと遅くなるケースがある bad_id_rsa: ASCII text
[ubuntu - SSH by key incredibly slow - Server Fault]( https://serverfault.com/questions/692449/ssh-by-key-incredibly-slow ) $ file good_id_rsa
good_id_rsa: PEM RSA private key
#### 鍵を使わずにssh ログインしたいときのsshオプション ```
``` bash なお、`bat`コマンドでも色がつくので違いがわかる
ssh -o PubkeyAuthentication=no $IP_ADDR
``` 秘密鍵の正しい形式
```
## ssh-agent -----BEGIN RSA PRIVATE KEY-----
### ssh-agentの設定 ......
`eval $(ssh-agent)`の中身(macの場合) -----END RSA PRIVATE KEY-----
```
``` bash
ssh-agent ### VSCodeのsshではgit情報を裏で処理しているための負荷が発生する
SSH_AUTH_SOCK=/var/folders/5d/540y5x9964n8msqxr77rkqr40000gn/T//ssh-91EQWwcjE3lC/agent.93691; export SSH_AUTH_SOCK; [Visual Studio CodeでのSSH接続により、EC2サーバーが高負荷になり動かなくなった - エキサイト TechBlog.]( https://tech.excite.co.jp/entry/2022/09/27/153341 )
SSH_AGENT_PID=93692; export SSH_AGENT_PID;
echo Agent pid 93692; ### sshの接続が遅い
``` 認証鍵を利用する際にDNSアクセスがあるため、DNSの指定がおかしいと遅くなるケースがある
[ubuntu - SSH by key incredibly slow - Server Fault]( https://serverfault.com/questions/692449/ssh-by-key-incredibly-slow )
shellごとに、`ssh-agent`を起動するのではなく、一度起動したssh-agentを使い回す方法が良い
#### 鍵を使わずにssh ログインしたいときのsshオプション
参考: [tmux で attach したら ssh-agent が切れる場合 #SSH - Qiita]( https://qiita.com/sonots/items/2d7950a68da0a02ba7e4 ) ``` bash
ssh -o PubkeyAuthentication=no $IP_ADDR
### ssh-add ```
`ssh-add`でgitの秘密鍵を複数登録すると最初に追加したキーのみが有効になる ## ssh-agent
### ssh-agentの設定
これは、`ssh-agent`がキーの登録順に接続を試し、最初に成功したキーで通信を行うためである `eval $(ssh-agent)`の中身(macの場合)
したがって、複数のgitの秘密鍵を`ssh-agent`では管理できない(gitに限った話ではない) ``` bash
ssh-agent
どうしても利用したい場合には、`-d`でキーを個別に除去したり、`-D`で全て除去する必要がある SSH_AUTH_SOCK=/var/folders/5d/540y5x9964n8msqxr77rkqr40000gn/T//ssh-91EQWwcjE3lC/agent.93691; export SSH_AUTH_SOCK;
SSH_AGENT_PID=93692; export SSH_AGENT_PID;
`ssh-add``-d`での削除には公開鍵情報が必要であり,それは、`ssh-add -L`で見ることができる echo Agent pid 93692;
```
下記で`XXX`個目に登録されているキーを削除できる
shellごとに、`ssh-agent`を起動するのではなく、一度起動したssh-agentを使い回す方法が良い
``` bash
ssh-add -d <(ssh-add -L | cut -d" " -f1,2 | awk 'NR==XXX') 参考: [tmux で attach したら ssh-agent が切れる場合 #SSH - Qiita]( https://qiita.com/sonots/items/2d7950a68da0a02ba7e4 )
```
### ssh-add
削除する際に下記のようなエラーがでても、実際には、そのファイルが存在しても、formatが正しくない時にも下記のメッセージが表示される
``` `ssh-add`でgitの秘密鍵を複数登録すると最初に追加したキーのみが有効になる
Bad key file XXX_id_rsa: No such file or directory
``` これは、`ssh-agent`がキーの登録順に接続を試し、最初に成功したキーで通信を行うためである
### 指定したキーが無視されているような挙動となっている したがって、複数のgitの秘密鍵を`ssh-agent`では管理できない(gitに限った話ではない)
`ssh-add`の結果は`~/.ssh/config``ssh -i`よりも優先されるため、注意
どうしても利用したい場合には、`-d`でキーを個別に除去したり、`-D`で全て除去する必要がある
### ⭐ssh接続先でgit cloneしたい
1. ホストマシンでssh-agentに秘密鍵を追加する `ssh-add``-d`での削除には公開鍵情報が必要であり,それは、`ssh-add -L`で見ることができる
下記のコマンドはシェルごとに実行する必要がある 下記で`XXX`個目に登録されているキーを削除できる
``` bash
eval $(ssh-agent) ``` bash
ssh-add ~/.ssh/github_id_rsa ssh-add -d <(ssh-add -L | cut -d" " -f1,2 | awk 'NR==XXX')
ssh-add -L ```
```
なお、すでにssh接続していた先のサーバにも上記の変更はリアルタイムに反映される(ホストマシンの`ssh-agent`の情報を利用しているためであると推測される) 削除する際に下記のようなエラーがでても、実際には、そのファイルが存在しても、formatが正しくない時にも下記のメッセージが表示される
```
2. `ssh`コマンドに`-A`オプションをつける or `~/.ssh/config``ForwardAgent yes`を追加する Bad key file XXX_id_rsa: No such file or directory
```
3. リモートでsshログインして、`ssh-add -L`して確かめてから、`git clone git@github.com:ORG/REPO.git`をする
### 指定したキーが無視されているような挙動となっている
#### ssh-agentの機能で適切にfetchできなかった原因 `ssh-add`の結果は`~/.ssh/config``ssh -i`よりも優先されるため、注意
まず、`ssh -T git@github.com`で確認する
### ⭐ssh接続先でgit cloneしたい
該当するgitのリモートのアドレスが原因である可能性がある 1. ホストマシンでssh-agentに秘密鍵を追加する
``` bash
$ git remote -v 下記のコマンドはシェルごとに実行する必要がある
origin github.com:ORG/REPO.git (fetch) ``` bash
origin github.com:ORG/REPO.git (push) eval $(ssh-agent)
$ git remote set-url origin git@github.com:ORG/REPO.git ssh-add ~/.ssh/github_id_rsa
$ git remote -v ssh-add -L
origin git@github.com:ORG/REPO.git (fetch) ```
origin git@github.com:ORG/REPO.git (push) なお、すでにssh接続していた先のサーバにも上記の変更はリアルタイムに反映される(ホストマシンの`ssh-agent`の情報を利用しているためであると推測される)
2. `ssh`コマンドに`-A`オプションをつける or `~/.ssh/config``ForwardAgent yes`を追加する
3. リモートでsshログインして、`ssh-add -L`して確かめてから、`git clone git@github.com:ORG/REPO.git`をする
#### ssh-agentの機能で適切にfetchできなかった原因
まず、`ssh -T git@github.com`で確認する
該当するgitのリモートのアドレスが原因である可能性がある
``` bash
$ git remote -v
origin github.com:ORG/REPO.git (fetch)
origin github.com:ORG/REPO.git (push)
$ git remote set-url origin git@github.com:ORG/REPO.git
$ git remote -v
origin git@github.com:ORG/REPO.git (fetch)
origin git@github.com:ORG/REPO.git (push)
``` ```
\ No newline at end of file