NAPT,踏み台,jump,ネットワーク

内部ネットワークを作成する意味

現在の研究室ではOS Ubuntu18.04のVMでDNSとDHCPが稼働しています. VM上でDNSとDHCPを稼働させるのではなく,コンテナとして稼働させる方針に決まりました. しかしDHCPを同じネットワーク上で2台稼働させるのは,問題が発生します. DHCP同士の衝突が発生し,正常な通信ができなくなってしまいます. そこで研究室内に更に内部のネットワークを構成することにしました.

DNS-DHCP_図-内部ネットワーク作成の意味.jpg (81.7 kB)

このように構成することで,DNS・DHCPは互いに干渉し合うことがなくなります.

ハードウェアの設定

ハードウェアとして以下の要素は192.168.100.0/24と192.168.21.0/24のネットワークを中継するJumpサーバと192.168.21.0/24のIPアドレスを持つDNS, DHCPサーバの2つとなります.

ただ2つのサーバを用意するだけではいけません.そこで必要になるのが仮想Nicと仮想スイッチです.

仮想Nicと仮想スイッチという言葉がありますが,そもそもNicとスイッチとはなんでしょう.NicはNetwork Interface Cardの略でコンピュータに取り付けるインターフェースです.仮想NicはVM上で使用されるインターフェースになります.簡単に言えば接続するための入り口だと思ってください.スイッチは通信を目的の機器に送るためのハードウェアのことを言います.それをVM間で行うのが仮想スイッチです. 参考URL https://atmarkit.itmedia.co.jp/icd/root/16/25168116.html https://www.sanwa.co.jp/product/network/lanhub/info.html

以下の具体例を見てみましょう! 図中のens34とens37が仮想NicでVM NetworkとDNS・DHCP Networkが仮想スイッチです.ネットワークが違う(192.168.100.0/24と192.168.21.0/24)に接続するためにはJumpサーバ,DNS, DHCPサーバだけではできないことがわかります. DNS-DHCP_図-Jumpサーバとensの役割.jpg (78.9 kB)

上の図を見るとJumpサーバに仮想Nicが2つあります.これはなぜかというとVM NetworkとDNS・DHCP NetworkごとにNicが必要になるためです.これがないとJumpサーバにsshできてもDNS・DHCPサーバにsshできません.

これを踏まえて作るものは以下の4つとなります. 1. Jumpサーバ,DNS・DHCPサーバ 1. 仮想Nic 1. 仮想スイッチ

では一つずつ作りましょう!

ますはJumpサーバ,DNS・DHCP用のVMをそれぞれ立てます.立て方は以下のesa記事を参考にしてください.ここでは資料通りにVMを作成します. https://cdsl-tut.esa.io/wiki/121 ※DNSやDHCPサーバのIPアドレス等が最初から決まっており,事前に設定したい場合は以下を参照してください ↓ VMの初期設定の際に以下の写真のようなネットワークの設定を行う画面で,VM Networkが接続されている仮想NICがens34ということが分かります.上記に記述したようにJumpサーバは仮想NICが複数必要です.そのため,「Create bond」を押してあらかじめNICを追加することで後に設定ファイルを変更する際に楽になります. VM作成_ネットワーク設定.jpg (46.6 kB) 「Create bond」を押したら,以下の画面になります.例えば今回追加するNicの名前は「ens35」として以下のNameに記述します.JumpサーバはVM NetworkとDNS・DHCP Networkを分けたいため,ens34のチェック欄にはチェックを入れません.Bond modeはNICの冗長性構成に関する設定です.今回はNICに冗長性を持たせる必要性がないため,blance-rrのままにします. VM作成_ネットワークアダプタの追加.jpg (30.7 kB) 作成できたら自身が設定したNICの名前(ここではens35)を選択してEdit DHCP4を選択します.MethodはManualを選択します.上から追加したいNICのサブネット,IPアドレス,ゲートウェイ,Name servers(キャッシュDNSのIPアドレス),検索Domainの設定を行います. VM作成_追加したネットワークの詳細設定.jpg (51.9 kB) サブネットは192.168.21/24とし,Addressesの欄には設定したいIPアドレスを入力する.設定するens35がゲートウェイになるため,ゲートウェイの欄は何も記述しません.Name servers,検索ドメインはens35より上の階層のDNSに問い合わせを行わないため,記述しません.

Subnet:192.168.21.1/24
Address:192.168.21.10
Gateway:
Name servers:
Search domain:

作成できたら次に仮想Nicと仮想スイッチを追加します.(ハードウェアの手順は以下の記事にまとめました!) https://cdsl-tut.esa.io/wiki/1435

ソフトウェアの設定

Jump Serverの役割

DNS DHCPをテスト環境のネットワークに作成することで現在稼働しているサーバとの干渉が起きなくなることについて触れましたが,Jump Serverはここでは何をするのでしょう? Jump Serverは一般的には以下の用途で使用されます. 以下はlinkから引用したものです. Jump server definition

Jump server refers to a secure computer that spans two or more networks, allowing users to connect to it from one network, and then “jump“ to another network. It’s also known as a jump host or a jump box.

Jump servers are used to manage and control access between networks, often serving as a gateway from a less trusted network (like a public network into a more trusted network (like an internal company network).

In cybersecurity, a jump server is similar to a VPN where a secure connection is established between the user and the server, but the jump server also provides additional layers of security like auditing features.

要約すると, ジャンプサーバーは異なるネットワーク間で安全な接続を提供し, 信頼性の低いネットワークから高いネットワークへのアクセスを管理するコンピュータであり VPNに似ているが追加のセキュリティ機能を提供する.

今回のケースにとてもマッチしていますね

今回は内部(Test ENV)から外部(LAB ENV)へ接続できればOKとします. 現時点のJump Serverの役割です. Jump-server.png (362.8 kB)

理由は内部で作成したVMにdockerをインストールしたり, imageをpullする必要があるからです. よく考えたら,SSHができるようにしたいので,逆の接続も一部許可したほうが良さそうですね(ESXiのUIでVMのコマンドライン操作するのは面倒なため).

NAPTをなぜ使用する?→ UFWを使用する理由

同じような技術でNATがあるが,NATの場合,内部にある複数のサーバが同時に接続できなくなるため,NAPT(Network Address Port Translation)を使用する. Linux系でNAPTを実装する際にはIPマスカレードと呼びます. https://www.liveon.ne.jp/glossary/ip_masquerade/

IPマスカレードを使用するにはiptablesのコマンドを実行する必要があります. UFW(Uncomplicated FireWall)はiptablesのラッパー(https://ubuntu-nikki.hatenadiary.org/entry/20100921/1285077768) なため,iptablesで実行できることはUFWでも実行可能です. そこでUFWに関する設定ファイルを変更することで,NAPTの設定ができるようになります.

今回設定するファイル

ネットワーク設定用

VM(Ubuntu22.04)のIP設定を行う際,以下のコマンドを実行し,ファイルを編集する必要があります. 以下のコマンドは「ハードウェアの設定」で示した図のJumpサーバとDNS・DHCPのような内部ネットワークVMの「/etc/netplan/」に存在するyamlファイルの内容です.

踏み台用VM - ens34 - ens34はVM Networkに接続しています. - 今回は固定のIPアドレスを割り当てたいため,自動でIPアドレスを割り当てるdhcp4をnoにして無効にします. - addressesには割り当てたいサブネットマスク24ビットの固定IPアドレスを記述します. - routesにはゲートウェイの設定を記述します.ゲートウェイの設定は「192.168.100.1」を指定します.defaultとはデフォルトゲートウェイのことで,割り当て先に無いIPアドレスの場合に転送する宛先のことです. - キャッシュDNSの設定を[8.8.8.8, 192.168.100.6]とします.「192.168.100.6」を設定した理由は,踏み台サーバである「192.168.100.21」とこのサーバのドメイン情報を繋ぎ合わせている場所が「192.168.100.6」のDNSであるためだからです.本来,このDNSに問い合わせた際に上の階層のIPアドレスを設定しているが,このDNSが何かしらの理由で落ちてしまっていた場合に備えて,「8.8.8.8」を設定します. - ens37 - 内部ネットワークも固定IPを割り当てるためdhcp4を無効にしました. - ens37にはゲートウェイを設定しません.内部ネットワークのゲートウェイがこのサーバになるためです. - addressesには内部ネットワーク接続VMに設定したいサブネットマスク24ビットの固定IPアドレスを記述します.上記で記述したように,このサーバがゲートウェイになることから最後の数値を1にし,192.168.21.1/24としました. - ens37は,キャッシュのDNSの設定をしていません.これはens34と違い,研究室のサーバの情報や,外部情報を取得する必要がないためです.

# This is the network config written by 'subiquity'
network:
  version: 2
  renderer: networkd
  ethernets:
    ens34:
      dhcp4: no
      addresses:
        - 192.168.100.21/24
      routes:
        - to: default
          via: 192.168.100.1
      nameservers:
        addresses: [8.8.8.8, 192.168.100.6]
    ens37:
      dhcp4: no
      addresses:
      - 192.168.21.1/24

内部ネットワーク接続VM - 内部ネットワーク(DNS・DHCP Network)のみの接続なため,VM Networkの設定は記述していない(後にESXiの設定からVM Networkの接続を外すため,そのまま残しておいてもよい). - 踏み台サーバの「ens34」と同じ理由により,キャッシュDNSの情報を記述します.踏み台サーバでIPアドレスを2つ記述したが,「8.8.8.8」のみでも問題ないです.

# This is the network config written by 'subiquity'
network:
  version: 2
  renderer: networkd
  ethernets:
    ens34: #内部ネットワーク
      dhcp4: no
      addresses:
      - 192.168.21.10/24
      routes:
      - to: default
        via: 192.168.21.1
      nameservers:
          addresses: [8.8.8.8]

設定ファイル変更後,反映させる必要があるため,以下のコマンドを実行

sudo netplan apply

NAPT設定用

今回使用するファイルは3つあります.下図はファイルの構成を示します.

file-architecture.png (302.1 kB)

それぞれのファイルは以下の役割を担っています. - /etc/default/ufw:ufwファイアウォールのデフォルト設定を定義 - /etc/ufw/sysctl.conf:カーネルのネットワークスタックに関連するパラメータを設定 - /etc/ufw/before.rules:ufwによって生成されたルールの前に適用されるカスタムiptablesルールを設定

Ubntu公式の説明がすごくわかりやすかったので,そこでの説明文も載せておきます. /lib/ufw/ufw-init→initialization script /etc/ufw/before.init→initialization customization script run before ufw is initialized /etc/ufw/after.init→initialization customization script run after ufw is initialized /etc/ufw/before[6].rules→rules file containing rules evaluated before UI added rules /etc/user[6].rules→rules file containing UI added rules (managed with the ufw command) /etc/ufw/after[6].rules→rules file containing rules evaluated after UI added rules /etc/default/ufw→high level configuration /etc/ufw/sysctl.conf→kernel network tunables /etc/ufw/ufw.conf→additional high level configuration

ということで3つのファイルを設定します.

/etc/default/ufwの設定

  • 今回作成する/etc/default/ufwを以下に示します. -今回変更する箇所はDEFAULT_FORWARD_POLICYです.これは受信したデータを他のサーバへ転送する際に適用される設定であり,今回は転送するサーバ(VM)をもう一つ作成したためACCEPTにし、他のサーバへ転送することを許可する
  • DEFAULT_INPUT_POLICYサーバに入ってくる通信のポリシーのことで、ACCEPTにしてしまうと全ポート開放することと同時になるためDROPにして,特定のポートのみを開放するように設定します.
  • DEFAULT_OUTPUT_POLICYはサーバから出て行く通信のポリシーのことで、ライブラリの追加や公開などは全てインターネットを介しているためACCEPTとします.
# /etc/default/ufw
#

# Set to yes to apply rules to support IPv6 (no means only IPv6 on loopback
# accepted). You will need to 'disable' and then 'enable' the firewall for
# the changes to take affect.
IPV6=yes

# Set the default input policy to ACCEPT, DROP, or REJECT. Please note that if
# you change this you will most likely want to adjust your rules.
DEFAULT_INPUT_POLICY="DROP"

# Set the default output policy to ACCEPT, DROP, or REJECT. Please note that if
# you change this you will most likely want to adjust your rules.
DEFAULT_OUTPUT_POLICY="ACCEPT"

# Set the default forward policy to ACCEPT, DROP or REJECT.  Please note that
# if you change this you will most likely want to adjust your rules
DEFAULT_FORWARD_POLICY="ACCEPT"

# Set the default application policy to ACCEPT, DROP, REJECT or SKIP. Please
# note that setting this to ACCEPT may be a security risk. See 'man ufw' for
# details
DEFAULT_APPLICATION_POLICY="SKIP"

# By default, ufw only touches its own chains. Set this to 'yes' to have ufw
# manage the built-in chains too. Warning: setting this to 'yes' will break
# non-ufw managed firewall rules
MANAGE_BUILTINS=no

#
# IPT backend
#
# only enable if using iptables backend
IPT_SYSCTL=/etc/ufw/sysctl.conf

# Extra connection tracking modules to load. IPT_MODULES should typically be
# empty for new installations and modules added only as needed. See
# 'CONNECTION HELPERS' from 'man ufw-framework' for details. Complete list can
# be found in net/netfilter/Kconfig of your kernel source. Some common modules:
# nf_conntrack_irc, nf_nat_irc: DCC (Direct Client to Client) support
# nf_conntrack_netbios_ns: NetBIOS (samba) client support
# nf_conntrack_pptp, nf_nat_pptp: PPTP over stateful firewall/NAT
# nf_conntrack_ftp, nf_nat_ftp: active FTP support
# nf_conntrack_tftp, nf_nat_tftp: TFTP support (server side)
# nf_conntrack_sane: sane support
IPT_MODULES=""

/etc/ufw/sysctl.confの設定

  • ufw/sysctl.confはファイアウォールのカーネルに関する設定を記述しています.
  • 今回変更するのはip_forward=1の箇所で,コメントアウトを外すのは、今回の踏み台サーバはipを他サーバ(他のVM)へ転送する(割り当てる)ため
  • そもそもIPv4とIPv6の違いは? →通信規格が違い、主な違いは以下の6つ →①接続方式、②通信速度、③割り当てられるIPアドレスの数、④セキュリティ強度、 ⑤接続できるサイトの種類,⑥対応機器が主な違い
  • IPv4:
    1. PPPoE
    2. PPPoEのため網終端装置が混み合ってしまい通信速度が低下することがある
    3. 2進法の32桁
    4. IPsecが必須でない
    5. 対応しているサイトが多い
    6. ほぼ全てのネットワーク機器が対応
  • IPv6:

    1. PPPoE+IPoE
    2. IPoEも扱えるためゲートウェイルータを通って直接的にインターネットへ接続する。よって混雑状況を無視して安定した通信速度が実現する
    3. 2進法の128桁
    4. IPsecが必須→4に比べて高いセキュリティを確保しやすい?
    5. 対応しているサイトが少ない
    6. 今までのネットワーク機器が使えないこともあるため、対応しているものを用意する必要がある
  • net/ipv4(ipv6)/conf/all/accept_redirects=0は全インターフェースでの IPv4 パケットおよび IPv6 パケットの転送を無効にします.有効にすると転送メッセージを悪用される危険性があります.

    #
    # Configuration file for setting network variables. Please note these settings
    # override /etc/sysctl.conf and /etc/sysctl.d. If you prefer to use
    # /etc/sysctl.conf, please adjust IPT_SYSCTL in /etc/default/ufw. See
    # Documentation/networking/ip-sysctl.txt in the kernel source code for more
    # information.
    #
    
    # Uncomment this to allow this host to route packets between interfaces
    net/ipv4/ip_forward=1
    #net/ipv6/conf/default/forwarding=1
    #net/ipv6/conf/all/forwarding=1
    
    # Disable ICMP redirects. ICMP redirects are rarely used but can be used in
    # MITM (man-in-the-middle) attacks. Disabling ICMP may disrupt legitimate
    # traffic to those sites.
    net/ipv4/conf/all/accept_redirects=0
    net/ipv4/conf/default/accept_redirects=0
    net/ipv6/conf/all/accept_redirects=0
    net/ipv6/conf/default/accept_redirects=0
    
    # Ignore bogus ICMP errors
    net/ipv4/icmp_echo_ignore_broadcasts=1
    net/ipv4/icmp_ignore_bogus_error_responses=1
    net/ipv4/icmp_echo_ignore_all=0
    
    # Don't log Martian Packets (impossible addresses)
    # packets
    net/ipv4/conf/all/log_martians=0
    net/ipv4/conf/default/log_martians=0
    
    #net/ipv4/tcp_fin_timeout=30
    #net/ipv4/tcp_keepalive_intvl=1800
    
    # Uncomment this to turn off ipv6 autoconfiguration
    #net/ipv6/conf/default/autoconf=1
    #net/ipv6/conf/all/autoconf=1
    
    # Uncomment this to enable ipv6 privacy addressing
    #net/ipv6/conf/default/use_tempaddr=2
    #net/ipv6/conf/all/use_tempaddr=2
    

/etc/ufw/before.rulesの設定

  • 変更点はNAT tableを追加した点です.
  • NAPTを使用するのにNAT tableを追加するのか
    • NAT tableがないと内部ネットワークと外部ネットワークで通信を行う際に,IPアドレスの変換が行うNATやNAPTが使えません.変換するために割り当てるIPアドレスを保持しておく割り当て表がなく,どのようなIPアドレスたポート番号を割り当てるべきかが分からないためです.
  • NATとNAPTの違い

    • NAT:IPアドレスを変換する
    • NAPT:IPアドレス:ポート番号のように変換して1対多を成立させる →ここでいう1はグローバルIPを使用するサーバ
  • iptablesとnatテーブルの違い

    • iptableはファイアウォールの設定ファイル
    • natテーブルはiptablesの一部で、IPアドレス・ポート番号の割当表

#
# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
#   ufw-before-input
#   ufw-before-output
#   ufw-before-forward
#

# NAT table rules
*nat
-F
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 192.168.21.0/24 -o ens34 -j MASQUERADE
COMMIT

# Don't delete these required lines, otherwise there will be errors
*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
# End required lines


# allow all on loopback
-A ufw-before-input -i lo -j ACCEPT
-A ufw-before-output -o lo -j ACCEPT

# quickly process packets for which we already have a connection
-A ufw-before-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-output -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-forward -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# drop INVALID packets (logs these in loglevel medium and higher)
-A ufw-before-input -m conntrack --ctstate INVALID -j ufw-logging-deny
-A ufw-before-input -m conntrack --ctstate INVALID -j DROP

# ok icmp codes for INPUT
-A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT
-A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT
-A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT
-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT

# ok icmp code for FORWARD
-A ufw-before-forward -p icmp --icmp-type destination-unreachable -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type time-exceeded -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type parameter-problem -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type echo-request -j ACCEPT

# allow dhcp client to work
-A ufw-before-input -p udp --sport 67 --dport 68 -j ACCEPT

#
# ufw-not-local
#
-A ufw-before-input -j ufw-not-local

# if LOCAL, RETURN
-A ufw-not-local -m addrtype --dst-type LOCAL -j RETURN

# if MULTICAST, RETURN
-A ufw-not-local -m addrtype --dst-type MULTICAST -j RETURN

# if BROADCAST, RETURN
-A ufw-not-local -m addrtype --dst-type BROADCAST -j RETURN

# all other non-local packets are dropped
-A ufw-not-local -m limit --limit 3/min --limit-burst 10 -j ufw-logging-deny
-A ufw-not-local -j DROP

# allow MULTICAST mDNS for service discovery (be sure the MULTICAST line above
# is uncommented)
-A ufw-before-input -p udp -d 224.0.0.251 --dport 5353 -j ACCEPT

# allow MULTICAST UPnP for service discovery (be sure the MULTICAST line above
# is uncommented)
-A ufw-before-input -p udp -d 239.255.255.250 --dport 1900 -j ACCEPT

# don't delete the 'COMMIT' line or these rules won't be processed
COMMIT
- これらのファイルを変更したらファイアウォールを有効にするために以下のコマンドを入力します.
sudo ufw reload
- 上記のコマンドでファイアウォールの再読み込みが出来ない場合は以下のコマンドでファイアウォールを有効にします.
sudo ufw enable
上記のコマンドにてファイアウォールを有効にしたら全ポートのアクセスがファイアウォールによってブロックされます.そのため,ESXiへアクセスし,コンソール画面から以下のコマンドを入力し,SSHのポートを開放します.
sudo ufw allow 22
上記のコマンドを入力したら,以下のコマンドを入力してファイアウォールの現在の状態を確認します.その結果,22番がallowになっていればsshできるはずです.
sudo ufw status
ここまでで踏み台サーバへSSHできることを確認したら,内部ネットワーク接続VMへ踏み台サーバからでないとSSHできないように設定します.まずはESXiへアクセスし,内部ネットワーク接続VMの「設定を編集」を押します.以下のような画面になると思うので,ネットワークアダプタ1に前述で記述したVM Networkの接続のチェックを外すことで接続を遮断し,保存します. ESXiの設定の編集画面.jpg (94.8 kB)

  • その後,踏み台サーバ以外からSSHできないことを確認したら,「Jump serverの役割」で述べたように内部ネットワーク接続VMから外部へ接続できるかを確認します.これを確認するために以下のコマンドを入力します.
    traceroute 8.8.8.8
    
  • この出力結果が意図した結果になっていれば(今回でいう8.8.8.8まで届いていれば)外部へ接続されていることを示します.
  • これは内部ネットワーク接続VMを起点として「8.8.8.8」であるgoogleのDNSサーバへの経路を表すしたものです.この時のIPアドレスは「192.168.21.10」であり,「/etc/netplan//etc/netplan//etc/netplan/00-installer-config.yaml」で設定したゲートウェイの「192.168.21.1」へ「192.168.21.0/24」の同一サブネット上に「8.8.8.8」の場所が存在するかを問い合わせる.なければ,次のゲートウェイ先である「192.168.100.1」へ問い合わせる.このように上の階層に問い合わせ続ける.
    traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
     1  _gateway (192.168.21.1)  0.134 ms  0.147 ms  0.190 ms
     2  192.168.100.1 (192.168.100.1)  0.665 ms  0.711 ms  0.750 ms
     3  10.203.63.1 (10.203.63.1)  2.371 ms  2.394 ms  2.415 ms
     4  10.203.30.1 (10.203.30.1)  2.436 ms  2.498 ms  2.520 ms
     5  10.200.254.254 (10.200.254.254)  2.445 ms  2.540 ms  3.160 ms
     6  150.99.194.97 (150.99.194.97)  3.291 ms  1.784 ms  1.795 ms
     7  150.99.11.133 (150.99.11.133)  3.080 ms  3.022 ms  3.033 ms
     8  101.203.88.173 (101.203.88.173)  3.573 ms  3.785 ms  3.810 ms
     9  108.170.242.193 (108.170.242.193)  6.169 ms 108.170.242.129 (108.170.242.129)  5.330 ms 108.170.242.193 (108.170.242.193)  5.378 ms
    10  108.170.235.121 (108.170.235.121)  5.556 ms 142.250.224.213 (142.250.224.213)  4.793 ms 216.239.58.205 (216.239.58.205)  4.815 ms
    11  dns.google (8.8.8.8)  4.840 ms  5.033 ms  3.238 ms
    

全体構成図

最終的な全体構成図です architectue.png (377.8 kB)