Linuxサーバにポートフォワードを設定して内部サーバに直接アクセスする

Page content

どんな時に使うのか

想定利用シーンはたくさんあるのだが、代替手段もいろいろあるので選択肢の一つとして考える。

  • ポート制限されており、制限されていないポートを利用して実際におこないたい接続をおこなう(アクセス制御回避)
  • 内部DBサーバに直接ODBC接続したいとか、内部WindowsサーバにRDPで接続したい等(緊急用の保守目的)
  • 踏み台経由でのアクセスが必要だが、直接接続しか対応していないアプリ等への対応(システム連携用)
  • 特定のポートだけを外部に提供したい(公開目的)

本来のアクセス制御を回避、網的に分離していることでセキュリティを担保している内部サーバへの外部接続手段を追加する等、実行によるリスクもあるため、接続可能IPアドレスを制限する、必要時にのみ起動する等、運用には気を付けたい。

今回のユースケース

image-20241002115110992

  • frontサーバは、通常利用PC等から接続が可能な網(192.168.0.xx)と、内部セグメント(10.0.0.x)の両方に接続されている
  • 外出や在宅時にも緊急メンテを目的として、backendサーバにアクセスする要件がある
  • 外出や在宅時もVPN接続によるfrontサーバへのアクセスは可能である。
  • backendサーバの操作はGUIが主であるため、リモートデスクトップでの接続が好ましい
  • ftontサーバにポートフォワーディング設定をおこない、frontサーバ経由でリモートデスクトップ接続をおこなう
  • 緊急用なので基本、常時利用できる状況としておき、サーバ等が再起動しても自動実行されるようにしたい

ssh関連の設定

一時的に実行してみる

ssh -NT -o -R 13389:10.0.0.3:3389 root@192.168.0.25

後述するsshdの設定不足がなければ、初回known-hostsへの登録、パスワードの入力後、サーバ上でフォワーディング用のポートがlistenする。

tcp        0      0 0.0.0.0:13389           0.0.0.0:*               LISTEN     

自動起動するためにサービス化、サービス化するために自動ログインできるような対応をしていく。

①SSHで自身のサーバにログインする際にパスワード無しでログインできるようにする

鍵をつくる 公開鍵をログイン先にコピー(ログイン先は現在のログイン先なのでlocalhostとする) 秘密鍵のパーミッション等を設定

# 以下rootで実行
ssh-keygen -t rsa -b 4096
ssh-copy-id root@localhost

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

②sshdの設定変更

gatewayPortsがyesじゃないと127.0.0.1でしか待ち受けできない Pubkey~AuthorizedKeys~は鍵での認証設定関連

/etc/ssh/sshd_config

設定ファイルで下記項目部分を変更

AllowTcpForwarding yes
GatewayPorts yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys

③sshdの再起動による設定有効化

systemctl restart sshd

Serviceファイルを作成

ポートフォワードを常に実行しておく、自動起動のためにサービス化をしておく。

nano /etc/systemd/system/test.service

/etc/systemd/system/test.service

[Unit]
Description=internal_server_forward
After=network.target

[Service]
User=root
ExecStart=/usr/bin/ssh -NT -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -R  [待ち受けポート]:[転送先]:[転送ポート]  [ root@待ち受けするアドレス]

RestartSec=3
Restart=always

[Install]
WantedBy=multi-user.target

追加したスクリプトの読み込み

systemctl daemon-reload

動作確認

known hostsに登録されていない場合は、下記のように対話的にknown hostsへの追加確認が行われるため、serviceでの起動に失敗する。 あらかじめsshの接続をおこなう等してknown hostsに追加しておく(1回だけでOK)

ssh root@10.0.0.2

The authenticity of host '[10.0.0.2]:22' can't be established.
ED25519 key fingerprint is SHA256:333vb++moAWgKOp48wZuTLCnwI/BWZXOLzQgiYN19qY.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[10.0.0.2]:22' (ED25519) to the list of known hosts.

指定したポートでlistenしていればOK。実際に(今回は13389ポート)接続し、転送先への接続ができればOK

systemctl start test
netstat -an | grep 13389

tcp        0      0 0.0.0.0:13389           0.0.0.0:*               LISTEN     

image-20241002115131304

備考

  • serviceをrootで実行しているが、待ち受けポートによってはroot権限は不要(1024以降のポートで待ち受ける場合)
  • その場合は、serviceファイルのUser及びusernameを任意のユーザに変更する

関連記事