AnsibleおよびTinc VPNを使用してサーバーインフラストラクチャを保護する方法

前書き

このチュートリアルでは、構成管理ツールであるAnsibleを使用して、TincでメッシュVPNをセットアップし、UbuntuサーバーとCentOSサーバー間のネットワーク通信を保護する方法を示します。

メッシュVPNは、サーバーが共有ネットワークを使用している場合に特に役立ちます。これは、サーバーが真にプライベートなネットワーク上で隔離されているかのように通信できるようにするためです。 VPNの認証および暗号化機能によって提供される追加のセキュリティレイヤーは、プライベートサービス(データベース、Elasticsearchクラスターなど)のネットワーク通信を不正アクセスや攻撃から保護します。 DigitalOceanのprivate networking featureを使用している場合、このセキュリティ機能は、同じリージョン内の同じチームまたはアカウントのサーバーに対してすでに有効になっています。
Mesh VPN Diagram

複数の構成およびキーファイルをすべてのVPNメンバーに配布する必要があるため、複数のサーバーにまたがってVPNを手動で構成および維持することは難しく、エラーが発生しやすくなります。 このため、構成管理ツールは、ある時点でメンバーが変更される可能性のある実用的なメッシュVPNセットアップに使用する必要があります。 任意の構成管理ツールを使用できますが、このチュートリアルでは一般的で使いやすいAnsibleを使用しています。 このチュートリアルで使用するAnsiblePlaybookansible-tincは、Ubuntu14.04およびCentOS7サーバーでテストされています。

バックグラウンドリーディング

付属のPlaybookがほとんどの作業を行うため、AnsibleやTincについてあまり知らなくても、このチュートリアルに従ってメッシュVPNをセットアップできるはずです。 ただし、設定する内容の詳細を理解できるように、ある時点でそれらがどのように機能するかを読みたい場合があります。

This Tinc VPN tutorialは、TincVPNを手動でインストールおよび構成する方法をカバーしています。 Ansibleを使用してプロセスを自動化すると、管理がはるかに簡単になります。

How to Install and Configure Ansibleは、Ansibleがどのように機能するかについての非常に高レベルの紹介を提供します。 システム管理者のタスクを自動化するためにAnsiblePlaybookの作成を開始する場合は、this tutorialを確認してください。

前提条件

ローカルマシン

ローカルマシンは、Ansible Playbookを実行する場所です。 これはローカルマシンである可能性があります(例: ラップトップ)またはサーバーの管理に使用する他のサーバー。 前述のように、各リモートサーバーにrootとして接続できる必要があります。

ローカルマシンにAnsible 2.0+がインストールされている必要があります。 インストールプロセスはオペレーティングシステムまたはディストリビューションによって異なるため、インストールする必要がある場合はofficial Ansible installation documentationを参照してください。

ローカルマシンにもGitがインストールされている必要があるため、ansible-tincPlaybookのコピーを簡単にダウンロードできます。 繰り返しになりますが、インストール手順はローカルマシンによって異なるため、official Git installation guideを参照してください。

リモートサーバー

リモートサーバーは、Tinc VPNを使用するように構成するホストです。 少なくとも2つから始める必要があります。 Ansible Playbookを使用するには、次の要件を満たす必要があります。

  • Ubuntu 14.04またはCentOS 7の実行

  • rootユーザーwith public key authenticationを介してローカルマシン(Ansibleがインストールされている)にアクセス可能

[.note]#Note: Playbookが使用するbug with the Ansible Synchronize moduleのため、現時点では別のリモートユーザーを使用することはできません。

rootのパスワード認証をまだ無効にしていない場合は、PermitRootLogin without-password/etc/ssh/sshd_configファイルに追加してから、SSHを再起動することで無効にできます。

同じデータセンター内にあるDigitalOceanドロップレットを使用している場合は、それらすべてでenable Private Networkingを使用する必要があります。 これにより、暗号化されたVPN通信にプライベートネットワークインターフェイスeth1を使用できるようになります。 提供されているPlaybookでは、すべてのVPNノードが同じネットワークデバイス名を使用すると想定しています。

Ansible-Tinc Playbookをダウンロード

開始する準備ができたら、git cloneを使用してPlaybookのコピーをダウンロードします。 ホームディレクトリに複製します。

cd ~
git clone https://github.com/thisismitch/ansible-tinc

次に、新しくダウンロードしたansible-tincディレクトリに移動します。

cd ansible-tinc

[.note]#Note:このチュートリアルの残りの部分では、ローカルマシンのansible-tincディレクトリにいることを前提としています。 すべてのAnsibleコマンドは、このディレクトリから実行する必要があります。 また、/etc/hostsを除いて、参照されるすべてのファイルは、このパスに関連しています。 hosts~/ansible-tinc/hostsを参照します。

次に、Playbookを使用してメッシュVPNを作成する方法を示します。 Ansibleに精通している場合は、Playbookの内容を参照するのに時間がかかることがあります。 基本的に、Tincを使用してメッシュVPNをインストールおよび構成し、各サーバーの/etc/hostsに便利なエントリを追加します。

ホストインベントリファイルの作成

Playbookを実行する前に、Tinc VPNに含めるサーバーに関する情報を含むhostsファイルを作成する必要があります。 ここで、hostsファイルの内容を確認します。

~/ansible-tinc/hosts example

[vpn]
node01 vpn_ip=10.0.0.1 ansible_host=192.0.2.55
node02 vpn_ip=10.0.0.2 ansible_host=192.0.2.240
node03 vpn_ip=10.0.0.3 ansible_host=198.51.100.4
node04 vpn_ip=10.0.0.4 ansible_host=198.51.100.36

[removevpn]

最初の行[vpn]は、そのすぐ下のホストエントリが「vpn」グループの一部であることを指定します。 このグループのメンバーには、Tinc mesh VPNが構成されます。

  • 最初の列は、ホストのインベントリ名、例の最初の行の「node01」、Ansibleがホストを参照する方法を設定する場所です。 この値は、Tinc接続を構成し、/etc/hostsエントリを生成するために使用されます。 Tincはホスト名でハイフンをサポートしていないため、ここではハイフンを使用しないでください。

  • vpn_ipは、ノードがVPNに使用するIPアドレスです。 これを、サーバーがVPN接続に使用するIPアドレスに割り当てます

  • ansible_hostは、ローカルマシンがノードに到達できる値に設定する必要があります(つまり、 実際のIPアドレスまたはホスト名)

したがって、この例では、次のようなメッシュVPNで構成する4つのホストがあります。

Example Mesh VPN Diagram

hostsファイルにVPNに含めるすべてのサーバーが含まれたら、変更を保存します。 重複するエントリ(ホスト名、vpn_ipアドレス、またはansible_host値)が含まれていないことを確認してください。

この時点で、インベントリファイル内のすべてのホストにAnsibleが接続できることをテストする必要があります。

ansible all -m ping

全員が緑色の「成功」メッセージで応答する必要があります。 いずれかの接続が失敗した場合は、hostsファイルでエラーをチェックし、問題のサーバーがすべてprerequisites sectionにリストされている要件を満たしていることを確認してから次に進んでください。

グループ変数を確認する

Playbookを実行する前に、/group_vars/allファイルの内容を確認することをお勧めします。

/group_vars/all

---

netname: nyc3
physical_ip: "{{ ansible_eth1.ipv4.address }}"

vpn_interface: tun0

vpn_netmask: 255.255.255.0
vpn_subnet_cidr_netmask: 32

最も重要な2つの変数は、physical_ipvpn_netmaskです。

  • physical_ipは、tincがバインドするIPアドレスを指定します。 ここでは、Ansible Factを利用して、eth1ネットワークデバイスのIPアドレスに設定しています。 DigitalOceanでは、eth1はプライベートネットワークインターフェイスであるため、パブリックネットワークインターフェイスeth0を使用する場合を除き、値を{{ ansible_eth0.ipv4.address }}に変更してPrivate Networkingを有効にする必要があります。

  • vpn_netmaskは、VPNインターフェースに適用されるネットマスクを指定します。 デフォルトでは、255.255.255.0に設定されています。これは、各vpn_ipがクラスCアドレスであり、同じサブネット内の他のホストとのみ通信できることを意味します。 たとえば、vpn_netmask255.255.0.0のようなものに変更してサブネットを拡大しない限り、10.0.0.x10.0.1.xホストと通信できません。

[.note]#Note: VPNのセキュリティ上の利点は、パブリックインターネットを介してサーバーに拡張できますが、通信には、非VPN接続と同じ遅延と帯域幅の制限があることに注意してください。

他の設定の説明は次のとおりです。

  • netnameはtincネット名を指定します。 デフォルトではnyc3に設定されています。

  • vpn_interfaceは、tincが使用する仮想ネットワークインターフェイスの名前です。 デフォルトではtun0です。

  • vpn_subnet_cidr_netmaskは32に設定されています。これは、メッシュVPNを構成しているため、単一ホストサブネット(ポイントツーポイント)を示します。 この値を変更しないでください。

グループ変数の確認が完了したら、次のステップに進む準備ができているはずです。

Tinc VPNを展開する

インベントリホストファイルを作成し、グループ変数を確認したら、Playbookを実行してTincを展開し、サーバー全体にVPNをセットアップする準備ができました。

ansible-tincディレクトリから、次のコマンドを実行してPlaybookを実行します。

ansible-playbook site.yml

Playbookの実行中、実行される各タスクの出力を提供する必要があります。 すべてが正しく構成されている場合は、いくつかのokchangedのステータスが表示され、failedのステータスはゼロになります。

PLAY RECAP *********************************************************************node01                     : ok=18   changed=15   unreachable=0    failed=0
node02                     : ok=18   changed=15   unreachable=0    failed=0
node03                     : ok=21   changed=19   unreachable=0    failed=0
node04                     : ok=21   changed=19   unreachable=0    failed=0

失敗したタスクがない場合、インベントリファイル内のすべてのホストは、VPNネットワークを介して相互に通信できる必要があります。

VPNをテストする

最初のホストにログインし、2番目のホストにpingを実行します。

ping 10.0.0.2

Playbookはインベントリホスト名を各メンバーのVPNIPアドレスにポイントする/etc/hostsエントリを自動的に作成するため、次のようにすることもできます(ホストの1つがAnsible%(でnode02という名前であると仮定) t2)sファイル):

ping node02

いずれにしても、有効なping応答が表示されるはずです。

[secondary_label Output:
PING node02 (10.0.0.2) 56(84) bytes of data.
64 bytes from node02 (10.0.0.2): icmp_seq=1 ttl=64 time=1.42 ms
64 bytes from node02 (10.0.0.2): icmp_seq=2 ttl=64 time=1.03 ms
...

他のノード間のVPN接続を自由にテストしてください。

[.note]#Note: Tincはポート655を使用します。 pingテストが機能しない場合は、各ノードのファイアウォールが、VPNが使用している実際のネットワークデバイスを介した適切なトラフィックを許可していることを確認してください。

テストが完了すると、メッシュVPNを使用する準備が整います。

サービスとアプリケーションを構成する

メッシュVPNがセットアップされたので、それを使用するようにバックエンドサービスとアプリケーションを構成する必要があります(適切な場合)。 つまり、VPNを介して通信する必要のあるサービスは、通常のプライベートIPアドレスではなく、適切なVPN IPアドレス(vpn_ip)を使用する必要があります。

たとえば、node01でNginxを使用し、node02でMySQLデータベースを使用してLEMPスタックを実行しているとします。 MySQLはVPNIPアドレス10.0.0.2にバインドするように構成する必要があり、PHPアプリケーションは10.0.0.2でデータベースに接続し、Nginxは192.0.2.55(node01のパブリックIPアドレス)をリッスンする必要があります。

別の例として、node01node02、およびnode03がElasticsearchクラスター内のノードである場合、Elasticsearchは10.0.0.110.0.0.2、および%を使用するように構成する必要があります。 (t5)sをノードIPアドレスとして。 同様に、クラスターに接続するクライアントもVPNアドレスを使用する必要があります。

ファイアウォールの考慮事項

VPNネットワークデバイス、「tun0」、またはVPN IPアドレスのトラフィックを許可するには、ファイアウォールルールを更新する必要がある場合があります。

サーバーを追加または削除する方法

新しいサーバーを追加

hostsファイルの[vpn]グループにリストされているすべてのサーバーは、VPNの一部になります。 新しいVPNメンバーを追加するには、新しいサーバーを[vpn]グループに追加してから、Playbookを再実行します。

ansible-playbook site.yml

サーバーを削除する

VPNメンバーを削除するには、削除するサーバーのhostsエントリを[removevpn]グループの下のファイルの下部に移動します。

たとえば、node04を削除する場合、hostsファイルは次のようになります。

ホスト— VPNからnode04を削除

[vpn]
node01 vpn_ip=10.0.0.1 ansible_host=192.0.2.55
node02 vpn_ip=10.0.0.2 ansible_host=192.0.2.240
node03 vpn_ip=10.0.0.3 ansible_host=198.51.100.4

[removevpn]
node04 vpn_ip=10.0.0.4 ansible_host=198.51.100.36

hostsファイルを保存します。 vpn_ipはオプションであり、[removevpn]グループメンバーには使用されないことに注意してください。

次に、Playbookを再実行します。

ansible-playbook site.yml

これにより、Tincが停止し、[removevpn]グループのメンバーからTinc構成とホストキーファイルが削除され、VPNから削除されます。

VPNからホストを削除すると、孤立したtincホストファイルと残りのVPNメンバーの/ etc / hostsエントリが作成されることに注意してください。 後で新しいサーバーをVPNに追加するが、廃止された名前を再利用しない限り、これは何にも影響しないはずです。 これが問題になる場合は、各サーバーの適切な/etc/hostsエントリを削除してください。

結論

TincとAnsibleを使用して、サーバーインフラストラクチャをメッシュVPNで保護する必要があります。 特定のニーズに合わせてプレイブックを変更する必要がある場合は、fork it on GitHubまでお気軽に。

がんばろう!

Related