結論

踏み台サーバー(Bastion・ジャンプサーバー)とは、外から内部のサーバーへ入る入口を1台にまとめ、認証・通す相手・記録をそこに集めるための中継用サーバーです。今は SSH の ProxyJump で「通すだけ」に絞って使うか、AWS の Session Manager などで踏み台そのものを置かない構成を選ぶのが主流です。

この記事でわかること

  • 踏み台の意味・仕組みと、置く理由・置かない理由
  • netns で3台を組み、ProxyJump・-L で届いた実物とログの原文
  • Session Manager・Azure Bastion などとの判断表

2026年10月29日更新|OpenSSH 9.6p1・ip netns で3台を組んで実行確認

手元の PC から内部のサーバーへは直接つながりません。間に置いた踏み台にだけ入口を開け、そこから内部へ中継します。

flowchart TD
    C[手元のPC] -->|SSH 22番だけ許可| B[踏み台サーバー]
    B -->|踏み台からだけ許可| I[内部サーバー]
    C -.->|直接は届かない| I

よく調べられることの答えを先にまとめます。

知りたいこと 答え 詳しい節
踏み台サーバーとは 内部のサーバーへ入るための中継用サーバー。入口を1つにまとめる 踏み台サーバー(Bastion)とは
bastion の意味 英語で「要塞・稜堡」。bastion host、jump server、jump host とも呼ぶ 踏み台サーバー(Bastion)とは
踏み台経由で SSH する方法 ssh -J 踏み台 内部、または ssh_config に ProxyJump ProxyJump(ssh -J)
踏み台経由で DB・Web を開く ssh -L 手元のポート:内部のアドレス:ポート 踏み台 ポートフォワード(ssh -L)
踏み台に秘密鍵を置くか 置かない。ProxyJump なら手元の鍵のまま内部へ認証できる 鍵の置き方
aws bastion は今も要るか Session Manager・EC2 Instance Connect Endpoint で置かない構成も選べる 踏み台を置かない構成
Azure Bastion とは Azure が運用する踏み台のサービス。VM にパブリック IP が要らない 踏み台を置かない構成
置くか置かないか クラウドの管理機能が使えるなら置かない方が管理は軽い 判断表

確認環境:Ubuntu 24.04.5 LTS(カーネル 6.18)の上で、ip netns(iproute2 6.1.0)を3つ作り(手元・踏み台・内部サーバー)、veth で「手元―踏み台」「踏み台―内部」の2本の線だけをつなぎました。sshd と ssh は OpenSSH 9.6p1(Ubuntu の openssh-server・openssh-client のパッケージを作業場所に展開)で、sshd の設定ファイル・ホスト鍵・ログ・利用者の鍵はすべて作業場所に置いています。内部サーバーには Python 3.13.18 の http.server を2つ(10.127.2.2:8080 と 127.0.0.1:9000)立て、curl 8.5.0 で開きました。ProxyJump・ssh_config・ssh -L・エージェント転送・sshd の制限(PermitOpen・ForceCommand・PermitTTY・AllowUsers)とログは手元で実行し、AWS Systems Manager Session Manager・EC2 Instance Connect Endpoint・Azure Bastion・Windows の OpenSSH と netsh は公式ドキュメントで確かめた範囲だけを書いています(クラウドには接続していません)。図は mermaid 11.16.0 で描画を確かめました(確認日 2026年10月29日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「踏み台サーバー(Bastion)とは|仕組み・ProxyJump・置かない構成」

踏み台サーバー(Bastion)とは:意味と別名

この節では、踏み台サーバーという言葉の意味と、bastion・ジャンプサーバーなどの別名が分かります。

踏み台サーバーとは、利用者が目的のサーバーにログインするとき、間に挟んで中継させるサーバーです。内部のサーバーは外から直接つながらないようにしておき、外からの入口は踏み台1台だけにします。運用担当はまず踏み台に入り、そこから内部へ進みます。

英語では bastion host(バスティオンホスト)と呼びます。bastion は城の「稜堡(りょうほ)・要塞」で、外に突き出して守りを固めた場所という意味です。日本語の「踏み台」は「足場にして先へ進む台」のたとえで、同じものを指します。ほかに jump server・jump host・jump box・ジャンプサーバー とも呼ばれます。

呼び方 意味の重心 よく出る場面
踏み台サーバー 経由して先へ進む 日本語の設計書・手順書
bastion host(バスティオン) 守りを固めた入口 AWS・Azure の資料(Azure Bastion)
jump server・jump host 飛び移る中継点 OpenSSH の -J(ProxyJump)、運用の会話
ゲートウェイサーバー 境界の出入口 オンプレミスのネットワーク図

プロキシサーバー・VPN との違い

プロキシサーバーは「利用者の通信を代わりに外へ出す」、踏み台は「管理者が内部へ入るための入口」です。どちらも中継しますが、向きと目的が違います。VPN は手元の PC を内部ネットワークの一員にする仕組みで、つながったあとは内部のどのサーバーにも届くのが普通です。踏み台は「踏み台から先の、許した相手だけ」に絞りやすい点が違います。

踏み台サーバー

管理者が内部サーバーへ入る入口

SSH・RDP などの運用の通信だけ

通す相手・利用者・時間を絞れる

プロキシ・VPN

プロキシは利用者の通信を外へ中継

VPN は PC をネットワークに参加させる

つながると届く範囲が広くなりがち

踏み台サーバーの仕組みと、置く理由

この節では、踏み台を置くと何が守られるのか、その代わりに何を背負うのかが分かります。

踏み台の価値は「外に開ける穴を1つにまとめ、そこで誰が・いつ・どこへ入ったかを確かめられること」です。内部のサーバーが10台あっても、外から開けるのは踏み台の SSH(22番)だけになります。内部のサーバーは「踏み台から来た通信だけ受け付ける」設定にします。

1入口が1つになる

外向きに開けるのは踏み台の22番だけ。内部のサーバーにパブリック IP を付けずに済む。

2通す人と時間を絞れる

踏み台に入れるのは会社や担当者の IP からだけ、作業の時間だけ起動、と決めやすい。

3記録が1か所に集まる

誰がどこから入ったかを、踏み台のログでまとめて追える。

AWS で踏み台を組む典型は、踏み台をパブリックサブネット、内部サーバーをプライベートサブネットに置き、セキュリティグループで次のように絞る形です。

対象 受け付ける通信(インバウンド) ねらい
踏み台 TCP 22 を、運用担当の拠点のグローバル IP からだけ 知らない場所からはログイン画面にすら届かない
内部サーバー(Linux) TCP 22 を、踏み台のセキュリティグループからだけ 踏み台を通らない経路を作らない
内部サーバー(Windows) TCP 3389(RDP)を、踏み台のセキュリティグループからだけ RDP も踏み台経由のみ
DB(RDS など) DB のポートを、アプリと踏み台からだけ メンテナンス時だけ踏み台から触る

踏み台が背負う負担

入口を1つにまとめるということは、その1台が最も狙われ、最も止められない1台になるということです。OS とOpenSSH の更新、利用者の鍵の追加と削除、ログの保管、監視、使わない時間の停止、費用が踏み台の担当者に乗ります。踏み台を置かない構成(後の節)が増えているのは、この負担を減らすためです。

踏み台を通さないと届かないことを確かめる(netnsで3台)

この節では、手元・踏み台・内部サーバーの3台を1台の Linux の中に作り、踏み台を通さないと内部に届かないことを確かめた結果が分かります。

ip netns(ネットワーク名前空間)を使うと、1台の Linux の中にネットワークの分かれた「別のマシン」を作れます。次の3つを作り、線は「手元―踏み台」「踏み台―内部」の2本だけにしました。

役 netns の名前 アドレス 動かしたもの
手元の PC t127-client 10.127.1.2 ssh・curl
踏み台 t127-bastion 10.127.1.1 と 10.127.2.1 sshd(利用者 jump だけ)
内部サーバー t127-inner 10.127.2.2 sshd(利用者 ops)・Web 2つ
ip netns add t127-client
ip netns add t127-bastion
ip netns add t127-inner
ip link add t127c0 netns t127-client type veth peer name t127b0 netns t127-bastion
ip link add t127b1 netns t127-bastion type veth peer name t127i0 netns t127-inner
ip -n t127-client  addr add 10.127.1.2/24 dev t127c0
ip -n t127-bastion addr add 10.127.1.1/24 dev t127b0
ip -n t127-bastion addr add 10.127.2.1/24 dev t127b1
ip -n t127-inner   addr add 10.127.2.2/24 dev t127i0

手元から内部サーバーへ直接つなぐと、こうなりました。

$ ip route
10.127.1.0/24 dev t127c0 proto kernel scope link src 10.127.1.2

$ ssh -o ProxyJump=none inner hostname
ssh: connect to host 10.127.2.2 port 22: Network is unreachable

$ curl http://10.127.2.2:8080/
curl: (7) Failed to connect to 10.127.2.2 port 8080 after 0 ms: Couldn't connect to server

手元に「10.127.2.0/24 は踏み台へ送る」という経路を足しても、届きませんでした。踏み台の netns は net.ipv4.ip_forward = 0(パケットを転送しない)だからです。

$ ip route add 10.127.2.0/24 via 10.127.1.1
$ ssh -o ProxyJump=none -o ConnectTimeout=5 inner hostname
ssh: connect to host 10.127.2.2 port 22: Connection timed out
$ curl -m 5 http://10.127.2.2:8080/
curl: (28) Connection timed out after 5002 milliseconds

踏み台はルーターではない

誤解踏み台を置けば、手元から内部のアドレスへそのまま通信できる
→
実際踏み台はパケットを転送しない。SSH でいったん踏み台に入り、許された中継(-J・-L)だけが内部へ届く

だからこそ「何を通したか」を踏み台で決め、記録できる

ProxyJump(ssh -J)で踏み台経由で接続する

この節では、ssh の -J(ProxyJump)で踏み台を経由して内部サーバーに入る方法と、その中で何が起きているかが分かります。

ProxyJump は、踏み台へ SSH でつなぎ、そこから内部サーバーの22番への TCP の中継を頼み、その中継の上で内部サーバーと改めて SSH を話す機能です。OpenSSH のマニュアル(ssh_config)は「最初に踏み台へ ssh 接続し、そこから最終の相手への TCP 転送を張る」と説明しています。OpenSSH 7.3 から使えます。

ssh -J jump@10.127.1.1 ops@10.127.2.2

手元で実行し、内部サーバー側から見た接続元を表示させました。

$ ssh -F ./config -J bastion ops@10.127.2.2 'echo $SSH_CONNECTION'
10.127.2.1 45176 10.127.2.2 22

内部サーバーから見ると、接続元は踏み台の内側のアドレス(10.127.2.1)です。手元の 10.127.1.2 は見えません。ssh -v で流れを追うと、2回の認証がどちらも手元の鍵で行われていました。

debug1: Setting implicit ProxyCommand from ProxyJump: /srv/s4/r17/t127/root/usr/bin/ssh -F /dev/shm/t127/client/config -v -W '[%h]:%p' bastion
debug1: Connecting to 10.127.1.1 [10.127.1.1] port 22.
debug1: Authenticating to 10.127.1.1:22 as 'jump'
debug1: Server accepts key: /dev/shm/t127/client/id_ed25519 ED25519 SHA256:kYmHHO+CNXBfP7xzmlTMcDEbuc47y48rn8OchPo6hF4 explicit
Authenticated to 10.127.1.1 ([10.127.1.1]:22) using "publickey".
debug1: channel_connect_stdio_fwd: 10.127.2.2:22
debug1: Authenticating to 10.127.2.2:22 as 'ops'
debug1: Server accepts key: /dev/shm/t127/client/id_ed25519 ED25519 SHA256:kYmHHO+CNXBfP7xzmlTMcDEbuc47y48rn8OchPo6hF4 explicit
Authenticated to 10.127.2.2 (via proxy) using "publickey".
1

ProxyJump を ProxyCommand に置き換える

ssh は自分自身をもう1つ起動し、ssh -W '[10.127.2.2]:22' bastion を実行する。-F で渡した設定ファイルも引き継がれた。

Setting implicit ProxyCommand

2

踏み台に jump として認証する

手元の鍵で踏み台に入る。シェルは起動しない。

Authenticated to 10.127.1.1

3

踏み台に「10.127.2.2:22 へつないで」と頼む

SSH の direct-tcpip という中継のチャネルを開く。踏み台はこの TCP をただ中継する。

channel_connect_stdio_fwd

4

中継の上で内部サーバーと SSH を話す

暗号化は手元と内部サーバーの間で行われ、踏み台は中身を読めない。内部への認証も手元の鍵で行う。

Authenticated to 10.127.2.2 (via proxy)

踏み台が2段以上あるときは、カンマで区切ると順に経由します(-J 踏み台1,踏み台2)。多段の書き方と、ProxyCommand で書く以前の方法は、関連記事「ssh configの書き方|踏み台・ポートフォワードの用途別テンプレート」で扱っています。

ssh_configのProxyJumpと、ssh -Gで確かめる

この節では、毎回 -J を打たずに済む ssh_config の書き方と、効いている設定を確かめる方法が分かります。

ssh_config に「内部サーバーは踏み台を経由する」と書いておくと、ssh inner だけで踏み台を通ります。今回使った設定です。

Host bastion
    HostName 10.127.1.1
    User jump
    IdentityFile /dev/shm/t127/client/id_ed25519
    IdentitiesOnly yes
    UserKnownHostsFile /dev/shm/t127/client/known_hosts
    StrictHostKeyChecking yes
    ForwardAgent no

Host inner
    HostName 10.127.2.2
    User ops
    ProxyJump bastion
    IdentityFile /dev/shm/t127/client/id_ed25519
    IdentitiesOnly yes
    UserKnownHostsFile /dev/shm/t127/client/known_hosts
    StrictHostKeyChecking yes

HostName には「踏み台から見た」内部サーバーのアドレスを書きます。手元から名前解決できなくても、踏み台が届けば接続できます。設定が効いているかは ssh -G で、実際に使われる値を確かめられます。

$ ssh -G -F ./config inner | grep -E '^(hostname|user|proxyjump|identityfile|forwardagent) '
user ops
hostname 10.127.2.2
identityfile /dev/shm/t127/client/id_ed25519
forwardagent no
proxyjump bastion

接続にかかった時間も測りました(各10回の中央値)。踏み台を1段はさむと、認証が2回になる分だけ伸びます。

284ms踏み台だけ10回の中央値。222〜366ms
432ms踏み台経由で内部へ10回の中央値。384〜495ms
2回鍵での認証踏み台と内部で1回ずつ

同じ1台の中の netns なので回線の遅れはほぼ無く、差の多くは SSH の鍵交換と認証です。回数が多い作業では ControlMaster で接続を使い回すと短くなります(設定例は上の関連記事)。

ポートフォワード(ssh -L)で内部のWeb・DBに届く

この節では、踏み台の先にある Web 画面や DB を、手元のブラウザや DB ツールで開く方法が分かります。

ssh -L 手元のポート:行き先のアドレス:行き先のポート 踏み台 と書くと、手元のポートへの接続が、踏み台から行き先へ中継されます。行き先のアドレスは「踏み台から見た」アドレスです。

$ ssh -F ./config -N -o ExitOnForwardFailure=yes -L 127.0.0.1:18080:10.127.2.2:8080 bastion &
$ ss -ltnp | grep 18080
LISTEN 0      128        127.0.0.1:18080      0.0.0.0:*    pid=5364
$ curl -i http://127.0.0.1:18080/
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.13.18
Content-type: text/html
inner app: hello from 10.127.2.2

内部の Web サーバーのログには、接続元として踏み台の内側のアドレスが残りました。

10.127.2.1 - - [30/Oct/2026 21:02:30] "GET / HTTP/1.1" 200 -

内部サーバーの「localhost だけ」で待つサービスに届く

DB や管理画面は、内部サーバーの 127.0.0.1 だけで待ち受けていることがあります。この場合は内部サーバー自体を ProxyJump の先にして、行き先を 127.0.0.1 にします。行き先の 127.0.0.1 は「内部サーバーから見た自分」です。

$ ssh -F ./config -N -L 127.0.0.1:19000:127.0.0.1:9000 inner &
$ curl http://127.0.0.1:19000/
admin api on inner 127.0.0.1:9000
やりたいこと コマンドの形 行き先のアドレスは誰から見たものか
内部の Web(8080)を手元で開く ssh -L 18080:10.127.2.2:8080 bastion 踏み台から見た内部サーバー
内部の localhost の DB を開く ssh -L 15432:127.0.0.1:5432 inner(inner は ProxyJump 経由) 内部サーバー自身
Windows の内部サーバーに RDP ssh -L 13389:内部のIP:3389 bastion のあと、RDP で localhost:13389 踏み台から見た Windows
RDS などマネージド DB ssh -L 13306:DBのエンドポイント:3306 bastion 踏み台から見た DB

手元の待ち受けは 127.0.0.1: を付けて手元だけにしておくと、同じ LAN の他の PC から転送を使われずに済みます。

踏み台サーバーの作り方:sshdを「通すだけ」に絞る

この節では、踏み台の sshd を「ログインはできず、決めた相手への中継だけできる」状態にする設定と、その効き目の実物が分かります。

ProxyJump だけで使うなら、踏み台でシェルを開く必要がありません。シェルを開けない・行き先を決めた相手に限る、と設定すると、踏み台に入れた人ができることは「許した中継」だけになります。今回の踏み台の sshd_config です。

ListenAddress 10.127.1.1:22
HostKey /dev/shm/t127/bastion/ssh_host_ed25519_key
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
AuthenticationMethods publickey
LogLevel VERBOSE
AllowUsers jump

Match User jump
    PermitTTY no
    X11Forwarding no
    AllowAgentForwarding no
    AllowStreamLocalForwarding no
    PermitTunnel no
    GatewayPorts no
    AllowTcpForwarding local
    PermitOpen 10.127.2.2:22 10.127.2.2:8080
    ForceCommand /bin/echo "This host is a jump host only."

内部サーバーの sshd には、踏み台から来た ops だけを受け付ける1行を入れました(AllowUsers ops@10.127.2.1)。sshd_config のマニュアルは、USER@HOST の形ではユーザー名と接続元を別々に照合すると説明しています。

この設定で、実際に何が起きたかを並べます。

試したこと 結果(原文) 効いた設定
ssh bastion(シェルを開く) This host is a jump host only.(すぐ切れる) ForceCommand
ssh -tt bastion PTY allocation request failed on channel 0 PermitTTY no
許していない 10.127.2.2:5432 へ中継 channel 0: open failed: administratively prohibited: open failed PermitOpen
踏み台自身の 127.0.0.1:22 へ中継 channel 0: open failed: administratively prohibited: open failed PermitOpen
root で踏み台に入る root@10.127.1.1: Permission denied (publickey). AllowUsers・PermitRootLogin
ssh inner(ProxyJump) 成功。内部サーバーでコマンドが動く PermitOpen の 10.127.2.2:22

踏み台の auth ログには、断った中継が行き先つきで残りました。

Received request from 10.127.1.2 port 45736 to connect to host 10.127.2.2 port 5432, but the request was denied.
Received request from 10.127.1.2 port 45740 to connect to host 127.0.0.1 port 22, but the request was denied.
User root from 10.127.1.2 not allowed because not listed in AllowUsers

踏み台を組むときに決めておくことを、チェックリストにまとめます。

  • 1入口の IP を絞るセキュリティグループ・ファイアウォールで、22番を拠点や VPN の IP からだけにする
  • 2パスワード認証を切り、鍵だけにするPasswordAuthentication no。鍵は1人1つにし、退職・異動で消す
  • 3シェルを開けない利用者で中継させるForceCommand・PermitTTY no。管理用の利用者は別に分ける
  • 4中継できる行き先を決めるPermitOpen に内部サーバーの22番などだけを書く
  • 5内部サーバーは踏み台からだけ受けるAllowUsers user@踏み台のIP とファイアウォールの両方で
  • 6ログを踏み台の外へ送るLogLevel VERBOSE。ログ基盤に送り、踏み台の中だけに置かない
  • 7更新と停止の担当を決めるOS・OpenSSH の更新、使わない時間の停止を誰がいつやるか

入口のファイアウォールを Linux で絞る方法は、関連記事「ufwとfirewalldの使い方|コマンド対応表とSSH締め出し対策」で扱っています。

鍵の置き方:エージェント転送よりProxyJump

この節では、踏み台に秘密鍵を置かない理由と、エージェント転送(ssh -A)ではなく ProxyJump を使う理由が分かります。

踏み台に秘密鍵を置くと、踏み台に入れる人や、踏み台を乗っ取った人がその鍵を使えてしまいます。踏み台に入ってから ssh 内部 と打つ使い方では、内部サーバー用の鍵が踏み台に必要になります。これを避けるために使われてきたのがエージェント転送(ssh -A)ですが、今は ProxyJump で済みます。

手元に ssh-agent を起動して鍵を読み込み、内部サーバーで SSH_AUTH_SOCK を見比べました。

$ ssh -F ./config inner 'echo "SSH_AUTH_SOCK=[$SSH_AUTH_SOCK]"'
SSH_AUTH_SOCK=[]

$ ssh -A -F ./config inner 'echo "SSH_AUTH_SOCK=[$SSH_AUTH_SOCK]"; ls -l $SSH_AUTH_SOCK'
SSH_AUTH_SOCK=[/tmp/ssh-vQrHOIvQPB/agent.6418]
srwxr-xr-x 1 ops ops 0 Oct 30 21:02 /tmp/ssh-vQrHOIvQPB/agent.6418

-A を付けると、接続している間、相手のサーバーに手元のエージェントへつながるソケットができます。OpenSSH のマニュアル(ssh_config の ForwardAgent)は、相手のサーバーでファイルの権限を越えられる利用者は、このソケットを通じて手元のエージェントの鍵で認証できる、鍵そのものは取り出せないが鍵を使った操作はできる、と注意しています。ProxyJump では、踏み台にも内部サーバーにもこのソケットはできず、認証は手元で完結します。

踏み台経由で内部へ入るとき

やってはいけない踏み台に秘密鍵を置く。または ssh -A 踏み台 で入り、踏み台から ssh 内部
→
代わりに手元から ssh -J 踏み台 内部。踏み台には公開鍵(authorized_keys)だけを置く

踏み台側でも AllowAgentForwarding no にしておく

sshd_config のマニュアルは、AllowAgentForwarding を no にしても、シェルを使える利用者は自分で転送の仕組みを入れられるため、シェルも拒否しないと安全にはならない、と書いています。踏み台で ForceCommand・PermitTTY no とあわせて使うのはこのためです。鍵の作り方そのものは、関連記事「SSH鍵の作成とGitHub接続|Permission deniedの対処法」で扱っています。

踏み台サーバーのログの残し方

この節では、踏み台と内部サーバーの sshd のログに何が残り、誰が入ったかをどう追うのかが分かります。

LogLevel VERBOSE にすると、どの鍵(指紋)で入ったかがログに残ります。既定の INFO より詳しく、利用者ごとに鍵を分けておけば「誰が」まで分かります。踏み台の auth ログ(今回は -E で作業場所のファイルに出しています。通常は /var/log/auth.log や journalctl)です。

Connection from 10.127.1.2 port 39642 on 10.127.1.1 port 22 rdomain ""
Accepted key ED25519 SHA256:kYmHHO+CNXBfP7xzmlTMcDEbuc47y48rn8OchPo6hF4 found at /dev/shm/t127/home/jump/.ssh/authorized_keys:1
Accepted publickey for jump from 10.127.1.2 port 39642 ssh2: ED25519 SHA256:kYmHHO+CNXBfP7xzmlTMcDEbuc47y48rn8OchPo6hF4
User child is on pid 5009
Received disconnect from 10.127.1.2 port 39642:11: disconnected by user
Disconnected from user jump 10.127.1.2 port 39642

内部サーバーのログでは、接続元はすべて踏み台(10.127.2.1)です。

Connection from 10.127.2.1 port 45176 on 10.127.2.2 port 22 rdomain ""
Accepted publickey for ops from 10.127.2.1 port 45176 ssh2: ED25519 SHA256:kYmHHO+CNXBfP7xzmlTMcDEbuc47y48rn8OchPo6hF4
Starting session: command for ops from 10.127.2.1 port 45176 id 0
Transferred: sent 3504, received 3484 bytes

1手元の IP は踏み台にだけ残る

内部サーバーのログは接続元がすべて踏み台になる。誰が来たかは踏み台のログと突き合わせる。

2鍵の指紋で人を見分ける

同じ利用者名でも、指紋(SHA256:…)が人ごとに違えば区別できる。共有の鍵では追えない。

3中身のコマンドは残らない

ProxyJump では踏み台は暗号化された中継しか見ない。内部での操作の記録は内部サーバー側で取る。

操作した内容まで残したい場合は、内部サーバー側で監査の仕組み(auditd など)を使うか、セッションの記録を持つマネージドサービス(次の節)を選びます。

踏み台を置かない構成(AWS Session Manager・EC2 Instance Connect Endpoint・Azure Bastion)

この節では、自分で踏み台を立てずに内部のサーバーへ入る、クラウドの公式の方法が分かります(いずれも公式ドキュメントで確かめた範囲で、接続はしていません)。

クラウドでは「踏み台の役」をクラウドの管理機能が受け持ち、SSH のインバウンドを開けない構成が選べます。AWS の Session Manager のドキュメントは、利点の1つ目に「インバウンドのポートを開けず、踏み台ホスト・ジャンプボックス・SSH 鍵の管理から解放される」と書いています。

  1. 1AWS Systems Manager Session ManagerEC2 の SSM Agent が外へつなぎに行く。インバウンドを開けず、IAM で許可。シェル操作のログを CloudWatch Logs・S3 に送れる
  2. 2EC2 Instance Connect EndpointVPC 内に置くエンドポイント経由で SSH・RDP。インスタンスにパブリック IP が要らない。追加料金なし(AZ をまたぐ転送料は別)
  3. 3Azure BastionAzure が運用する踏み台(PaaS)。ポータルから 443 の TLS 経由で RDP・SSH。VM にパブリック IP が要らない
  4. 4自前の踏み台(EC2・VM に sshd)どのクラウド・オンプレミスでも同じ形で使える。更新・鍵・ログは自分で持つ

AWS Systems Manager Session Manager

EC2 に入っている SSM Agent が AWS のエンドポイントへ外向きにつなぎ、利用者はその経路でシェルに入ります。公式ドキュメントによると、セッションの記録は CloudWatch Logs や S3 に送れます。ただしポートフォワードや SSH を Session Manager の上で使うセッションはログの対象外で、理由は SSH が中身を暗号化し、Session Manager はトンネルとしてだけ働くためと説明されています。IAM ロール・VPC エンドポイント・プラグインの設定手順は、関連記事「Session ManagerでEC2に接続する方法|SSH鍵なしの手順」で扱っています。

EC2 Instance Connect Endpoint

公式ドキュメントは「踏み台ホストを使わず、VPC がインターネットに直接つながっていなくても、インターネットからインスタンスへ安全に接続できる」と説明しています。SSH は ssh の ProxyCommand に aws ec2-instance-connect open-tunnel を指定する形、RDP は 3389 番へのトンネルです。インスタンス側のセキュリティグループは、エンドポイントからの SSH を受け付けるようにします。制限として、1つのエンドポイントの同時接続は20まで、確立した TCP 接続の最長は1時間(3,600秒)と書かれています(2026年10月29日時点)。

ssh -i my-key-pair.pem ec2-user@i-1234567890abcdef0 \
    -o ProxyCommand='aws ec2-instance-connect open-tunnel --instance-id i-1234567890abcdef0'

Azure Bastion

Microsoft Learn は Azure Bastion を、ポータルから TLS 経由、またはローカルのネイティブの SSH・RDP クライアントで、VM へ安全に接続するフルマネージドの PaaS と説明しています。VM 側にはパブリック IP・エージェント・特別なクライアントが要りません。一方で Bastion 自体は、Basic・Standard・Premium では専用のサブネット(AzureBastionSubnet)とパブリック IP が必要で、Premium ではパブリック IP を使わない構成も選べます(2026年10月29日時点)。

SKU 公式の説明の要点
Developer(開発者) 無料。共有の基盤で、一度に1台の VM。一部のリージョンのみ
Basic 固定の容量の専用デプロイ
Standard ネイティブクライアント接続・共有リンク・IP ベースの接続・ファイル転送など
Premium Standard の機能に加え、セッションの記録・プライベートのみの構成

料金は SKU と時間で変わるため、各社の料金ページで確かめます。

Windowsから踏み台を使う(OpenSSH・RDP)

この節では、Windows の PC から踏み台を経由する方法と、Windows の内部サーバーへ RDP で入る方法が分かります(Microsoft の公式ドキュメントで確かめた範囲)。

Windows 10(ビルド 1809)以降と Windows Server 2019 以降では、OpenSSH を使えます。Microsoft Learn の「OpenSSH for Windows の概要」は、この版を前提条件として挙げ、まず「オプション機能」で OpenSSH が入っているかを確かめる手順を示しています。入っていれば、PowerShell やコマンドプロンプトで、この記事と同じ ssh -J・ssh -L を使えます。設定ファイルは利用者のフォルダーの .ssh\config です。

1

踏み台へ -L を張る

ssh -N -L 127.0.0.1:13389:内部のIP:3389 踏み台 を実行したままにする。

PowerShell

2

リモートデスクトップで手元につなぐ

接続先に localhost:13389 を入れる。通信は踏み台経由で内部の Windows の 3389 番へ届く。

mstsc

3

作業が済んだら ssh を止める

-L を張った ssh を Ctrl+C で止めると、手元の 13389 番も閉じる。

後始末

PuTTY・Tera Term・MobaXterm などの SSH クライアントにも、踏み台の経由やポート転送の設定があります。項目の名前はソフトごとに違うため、各ソフトの説明書で確かめます。

踏み台が Windows で OpenSSH を使えない場合、Windows の netsh interface portproxy で TCP を中継する方法も公式に書かれています。ただし認証の無い TCP の中継になるため、受け付ける相手をファイアウォールで絞り、作業が済んだら delete v4tov4 で消します。

netsh interface portproxy add v4tov4 [listenport=]<integer>|<servicename> [connectaddress=]<IPv4 address>|<hostname>
                                     [connectport=]<integer>|<servicename> [listenaddress=]<IPv4 address>|<hostname>
netsh interface portproxy show all

ssh コマンドのオプション全体は、関連記事「ssh コマンドの使い方まとめ|鍵・ポート指定・config・接続エラー対処」で扱っています。

よくあるエラーとつまずき(原文)

この節では、踏み台経由の接続で出たエラーの原文と、どこを直すかが分かります。どれも手元の3台で実際に起こしたものです。

出た文言(原文) 起きたこと 直す場所
ssh: connect to host 10.127.2.2 port 22: Network is unreachable ProxyJump を通らず、内部へ直接つなごうとした ssh_config の Host 名・ProxyJump の書き漏れ
ssh: connect to host 10.127.1.1 port 22: Connection refused / Connection closed by UNKNOWN port 65535 踏み台の sshd が止まっていた 踏み台の起動・22番の待ち受け
channel 0: open failed: administratively prohibited: open failed / stdio forwarding failed 踏み台が、その行き先への中継を断った 踏み台の PermitOpen・AllowTcpForwarding、HostName・Port の誤り
No ED25519 host key is known for 10.127.2.2 and you have requested strict checking. / Host key verification failed. 内部サーバーのホスト鍵が known_hosts に無い 内部サーバーのホスト鍵を確かめて登録する
admin@10.127.2.2: Permission denied (publickey). 内部サーバーが受け付けない利用者名で入ろうとした 内部サーバーの User・authorized_keys・AllowUsers
bind [127.0.0.1]:18080: Address already in use / Could not request local forwarding. -L の手元のポートを別のプログラムが使っていた 手元のポート番号を変える
PTY allocation request failed on channel 0 シェルを禁止した踏み台に -t で入ろうとした 踏み台には入らず ssh -J で内部へ

ホスト鍵の確認は、踏み台と内部の2台分

ProxyJump でも、ホスト鍵の確認は踏み台と内部サーバーの両方で行われます。手元の known_hosts に内部サーバーの行が無いと、上の表のとおり Host key verification failed. で止まりました。初めてつなぐときは、管理者から聞いた指紋と、表示される指紋を見比べてから登録します。

-J を使うと known_hosts が別のファイルになることがある

ssh -F ./config -J bastion ops@10.127.2.2 と打ったとき、最初は Host key verification failed. になりました。ops@10.127.2.2 が設定ファイルの Host inner に当たらず、inner 用に書いた UserKnownHostsFile が使われなかったためです。設定ファイルで Host 名を決めたら、ssh inner のようにその名前で呼ぶと取り違えが起きません。

ProxyJump と ProxyCommand を両方書く

ssh_config のマニュアルは、ProxyJump と ProxyCommand は競い合い、先に書かれた方が効いて後の方は無視されると説明しています。Host * に ProxyCommand を書いていると、個別の ProxyJump が効かないことがあります。迷ったら ssh -G で proxyjump と proxycommand の行を見ます。

踏み台を置くか・置かないかの判断表

この節では、自前の踏み台・クラウドのマネージドの方法・VPN のどれを選ぶかを、条件ごとに判断できます。

クラウドの管理機能が使える環境なら、踏み台を置かない方が管理するものは減ります。一方で、オンプレミスや複数のクラウドをまたぐ環境、SSH の道具(scp・rsync・Ansible など)をそのまま使いたい環境では、自前の踏み台が今も素直な選択です。

条件 向く方法 理由
AWS の EC2 だけ。インバウンドを1つも開けたくない Session Manager SSM Agent が外へつなぐ形で、鍵の配布も要らない
AWS で、いつもの ssh・RDP の道具を使いたい EC2 Instance Connect Endpoint ProxyCommand で ssh に組み込め、パブリック IP が要らない
Azure の VM。ブラウザから入れればよい Azure Bastion 運用は Azure 側。記録は Premium
操作内容の記録(監査)が要件にある Session Manager のシェル・Azure Bastion Premium、または内部での監査 ProxyJump の踏み台は中身を見ない
オンプレミス・複数クラウド・ネットワーク機器 自前の踏み台(ProxyJump) どこでも同じ形で使える
社員が内部の Web システムを日常的に使う VPN・ゼロトラスト型のアクセス 踏み台は管理者の運用向けで、利用者向けではない
開発用の1台だけで、短い期間 自前の踏み台を作業の時だけ起動、または Session Manager 止めておけば外から届かない

自前の踏み台を選ぶとき

ProxyJump だけで使い、シェルを開けない

PermitOpen で行き先を決める

鍵は1人1つ、ログは外へ送る

置かない構成を選ぶとき

IAM・Entra ID の権限が入口になる

ポート転送や SSH 経由はログの範囲を確かめる

同時接続・接続時間の上限を確かめる

よくある質問

Q. 踏み台サーバーとは何ですか? A. 外から内部のサーバーへ入るとき、間に挟んで中継させるサーバーです。外に開ける入口を1台にまとめ、そこで認証・通す相手・記録を管理します。bastion host・ジャンプサーバーとも呼びます。

Q. bastion とはどういう意味ですか? A. 英語で城の「稜堡・要塞」のことです。守りを固めた入口というたとえから、踏み台サーバーを bastion host と呼びます。Azure のサービス名(Azure Bastion)にも使われています。

Q. 踏み台サーバーとプロキシサーバーの違いは何ですか? A. プロキシは利用者の通信を代わりに外へ出す中継、踏み台は管理者が内部のサーバーへ入るための入口です。踏み台は「許した行き先への運用の通信だけ」を通します。

Q. 踏み台を置けば、手元から内部のアドレスへそのまま届きますか? A. 届きません。手元の netns で確かめたところ、経路を足しても Connection timed out でした。踏み台はパケットを転送せず、ssh -J や -L で頼んだ中継だけを通します。

Q. 踏み台に秘密鍵を置いてもよいですか? A. 置かない方が安全です。ssh -J(ProxyJump)なら、踏み台にも内部サーバーにも手元の鍵で認証でき、踏み台には公開鍵だけを置けば済みます。

Q. ssh -A(エージェント転送)と ProxyJump はどちらを使いますか? A. ProxyJump です。-A を付けると、接続中は相手のサーバーに手元のエージェントへつながるソケットができ、OpenSSH のマニュアルも注意して使うよう書いています。

Q. 踏み台経由で DB に GUI ツールからつなぐには? A. ssh -L 127.0.0.1:15432:DBのアドレス:5432 踏み台 を実行したまま、GUI ツールの接続先を 127.0.0.1:15432 にします。DB のアドレスは踏み台から見たものを書きます。

Q. AWS で踏み台(bastion)は今も必要ですか? A. 必須ではありません。Session Manager や EC2 Instance Connect Endpoint を使うと、踏み台を置かずに接続できます。オンプレミスとまたぐ場合や、ssh の道具をそのまま使いたい場合は、自前の踏み台も選択肢です。

Q. Azure Bastion を使うと VM にパブリック IP は要りますか? A. VM には要りません。Bastion 自体は、Basic・Standard・Premium で専用サブネットとパブリック IP が必要です(Premium にはパブリック IP を使わない構成もあります)。

Q. 踏み台のログで、誰が内部サーバーに入ったか分かりますか? A. 踏み台の auth ログに、接続元の IP と鍵の指紋が残ります(LogLevel VERBOSE)。内部サーバーのログは接続元がすべて踏み台になるため、時刻と指紋で突き合わせます。操作内容までは残りません。

Q. 踏み台は常に起動しておくものですか? A. 作業の時だけ起動し、終わったら止める運用もよく使われます。止めている間は外から届かず、費用も抑えられます。

まとめ

  • 踏み台サーバー(Bastion・ジャンプサーバー)は、内部のサーバーへ入る入口を1台にまとめる中継用サーバーです。
  • 踏み台はパケットを転送しません。手元の netns でも、ssh -J・-L で頼んだ中継だけが内部へ届きました。
  • 踏み台には秘密鍵を置かず、エージェント転送ではなく ProxyJump を使います。sshd は ForceCommand・PermitTTY no・PermitOpen で「通すだけ」に絞れます。
  • 誰が入ったかは踏み台の auth ログ(鍵の指紋)で追い、内部での操作の記録は別の仕組みで取ります。
  • AWS の Session Manager・EC2 Instance Connect Endpoint、Azure Bastion を使えば、踏み台を置かない構成も選べます。判断表で環境に合う方法を選びます。

参考・出典

いずれも 2026年10月29日に確認しました。

  • OpenBSD manual pages「ssh_config(5)」(ProxyJump・ForwardAgent):https://man.openbsd.org/ssh_config
  • OpenBSD manual pages「sshd_config(5)」(PermitOpen・ForceCommand・PermitTTY・AllowAgentForwarding・AllowUsers):https://man.openbsd.org/sshd_config
  • OpenBSD manual pages「ssh(1)」(-J・-L・-W):https://man.openbsd.org/ssh
  • OpenSSH「Release notes」(OpenSSH 7.3 の ProxyJump):https://www.openssh.com/releasenotes.html
  • AWS「AWS Systems Manager Session Manager」:https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html
  • AWS「Connect to your instances using EC2 Instance Connect Endpoint」:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/connect-with-ec2-instance-connect-endpoint.html
  • AWS「Connect to an Amazon EC2 instance using an EC2 Instance Connect Endpoint」:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/connect-using-eice.html
  • Microsoft Learn「Azure Bastion とは」:https://learn.microsoft.com/ja-jp/azure/bastion/bastion-overview
  • Microsoft Learn「OpenSSH for Windows の概要」:https://learn.microsoft.com/ja-jp/windows-server/administration/openssh/openssh_install_firstuse
  • Microsoft Learn「netsh interface」(portproxy):https://learn.microsoft.com/ja-jp/windows-server/networking/technologies/netsh/netsh-interface-portproxy
  • iproute2「ip-netns(8)」:https://man7.org/linux/man-pages/man8/ip-netns.8.html

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「踏み台サーバー(Bastion)とは|仕組み・ProxyJump・置かない構成」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ
参加受付中

AI駆動開発、 無料セミナー