以前に紹介した以下の記事で、AWS上のAmazonLinux2にOpenVPNサーバを構築しました。
AWS上のEC2でOpenVPNサーバを構築する
https://syachiku.net/ec2openvpn-1/
ただし、OpenVPNサーバを構築するには証明局や証明書の作成などのかなり多くの手順が必要となり複雑です。
そこで、構成管理ツールであるAnsibleを利用してOpenVPNの構築をコード化(IaC)してみました。
ansible-playbookのコマンド一発で簡単にOpenVPNサーバが構築できるようにします。
1. 前提
- EC2上に素のAmazonLinux2のインスタンスは用意されている
- 証明局とサーバ証明書、クライアント証明書は新規で作成する
- 細かいansibleの利用方法については解説しません。
2. 構築処理の流れ
基本的には以下の記事と同じ手順で構築しています。
AWS上のEC2でOpenVPNサーバを構築する
https://syachiku.net/ec2openvpn-1/
3. 作成したansible playbookについて
作成したansible playbookについて記載した後に、実際の構築手順について説明したいと思います。
3.1. ディレクトリ構成
/etc/ansible/以下のディレクトリは以下のようにしました。
localhostに対して実行するのでhostsファイルは不要です。 ベストプラクティスに沿って構築しているつもりです。
/etc/ansible/
├── ansible.cfg
├── hosts
├── roles
│ └── vpn
│ ├── files
│ │ ├── client.ovpn
│ │ └── server.conf
│ ├── handlers
│ │ └── main.yml
│ └── tasks
│ └── main.yml
├── site.yml
└── vars
└── variables.yml
3.2. site.yml
こんな感じです。localhostに対してvpnのroleを実施しています。
- hosts: localhost
become: yes
become_user: root
vars_files:
- ./vars/variables.yml
roles:
- vpn
3.3. vars/variables.yml
変数を格納していますが、今回はたったこれだけです。今後の拡張を考えて一応変数にしました。
openvpn_easyrsa_path: /usr/share/easy-rsa/3
3.4. roles/vpn/tasks/main.yml
ここがタスクのメインですamazon-linux-extrasを利用する方法がパッと調べてもなかったのでshellで実行しています。
- name: enable amazon-linux-extras epel
shell: "amazon-linux-extras install -y epel"
- name: install openvpn
yum:
name: openvpn
enablerepo: amzn2extra-epel
state: present
- name: install openvpn and easy-rsa
yum:
name: "{{ item }}"
enablerepo: amzn2extra-epel
state: present
update_cache: yes
with_items: [easy-rsa, openvpn]
- name: ensure /etc/openvpn/easy-rsa exists
ansible.builtin.file:
path: /etc/openvpn/easy-rsa
state: directory
mode: "0755"
- name: easyrsa init-pki
ansible.builtin.command:
cmd: "/usr/share/easy-rsa/3/easyrsa init-pki"
chdir: /etc/openvpn/easy-rsa
creates: /etc/openvpn/easy-rsa/pki
- name: easyrsa build-ca
ansible.builtin.command:
cmd: "/usr/share/easy-rsa/3/easyrsa build-ca nopass"
chdir: /etc/openvpn/easy-rsa
creates: /etc/openvpn/easy-rsa/pki/ca.crt
environment:
EASYRSA_BATCH: "yes"
- name: easyrsa gen-dh
ansible.builtin.command:
cmd: "/usr/share/easy-rsa/3/easyrsa gen-dh"
chdir: /etc/openvpn/easy-rsa
creates: /etc/openvpn/easy-rsa/pki/dh.pem
- name: easyrsa build-server-full server nopass
ansible.builtin.command:
cmd: "/usr/share/easy-rsa/3/easyrsa build-server-full server nopass"
chdir: /etc/openvpn/easy-rsa
creates: /etc/openvpn/easy-rsa/pki/issued/server.crt
- name: easyrsa build-client-full client nopass
ansible.builtin.command:
cmd: "{{ openvpn_easyrsa_path }}/easyrsa build-client-full client nopass"
chdir: /etc/openvpn/easy-rsa
creates: /etc/openvpn/easy-rsa/pki/issued/client.crt
- name: openvpn --genkey --secret /etc/openvpn/easy-rsa/pki/ta.key
ansible.builtin.command:
cmd: openvpn --genkey --secret /etc/openvpn/easy-rsa/pki/ta.key
creates: /etc/openvpn/easy-rsa/pki/ta.key
- name: copy files to /etc/openvpn/server
ansible.builtin.copy:
src: /etc/openvpn/easy-rsa/pki/{{ item }}
dest: /etc/openvpn/{{ item | basename }}
mode: "0640"
remote_src: yes
loop:
- ca.crt
- dh.pem
- ta.key
- issued/server.crt
- private/ca.key
- private/server.key
- name: copy files for client to /home/ec2-user
ansible.builtin.copy:
src: /etc/openvpn/easy-rsa/pki/{{ item }}
dest: /home/ec2-user/{{ item | basename }}
mode: "0666"
remote_src: yes
loop:
- ca.crt
- ta.key
- issued/client.crt
- private/client.key
- name: copy openvpn config file
copy:
src: server.conf
dest: /etc/openvpn/server.conf
owner: root
group: root
mode: 0644
notify: vpn restart
- name: copy openvpn client ovpn file
copy:
src: client.ovpn
dest: /home/ec2-user/client.ovpn
owner: root
group: root
mode: 0644
- name: enable ipv4.ip_forward
sysctl:
name: net.ipv4.ip_forward
value: '1'
state: present
sysctl_set: yes
reload: true
- name: start and enable openvpn
ansible.builtin.service:
name: "openvpn@server"
state: started
enabled: yes
3.5. roles/vpn/handlers/main.yml
OpenVPNサーバの再起動コマンドです。
- name: vpn restart
shell: systemctl restart openvpn@server
3.6. roles/vpn/files
- server.conf
- push routeやDNSなどの設定は適宜変更してください。
- 443ポートでVPN接続するようにしています。
port 443
proto tcp
dev tun
ca ca.crt
cert server.crt
key server.key # This file should be kept secret
dh dh.pem
server 192.168.10.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "route 10.1.0.0 255.255.0.0"
push "dhcp-option DNS 10.1.100.4"
push "dhcp-option DNS 10.1.200.144"
keepalive 10 120
tls-auth ta.key 0 # This file is secret
cipher AES-256-CBC
persist-key
persist-tun
status openvpn-status.log
log openvpn.log
log-append openvpn.log
verb 3
explicit-exit-notify 0
- client.ovpn
- remoteのxx.xx.xx.xxは後でVPNサーバのPublicIPに手動で変更します
client
dev tun
proto tcp
remote xx.xx.xx.xx 443
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client.crt
key client.key
remote-cert-tls server
tls-auth ta.key 1
cipher AES-256-CBC
verb 3
4. 結果としてできるもの
- AmazonLinux2のOpenVPNサーバがインストールされ、証明書関連もセットアップがされて、OpenVPNサービスが起動します。
- クライアント(PC)で利用する証明書と設定ファイル(ひな形)が作成されて/home/ec2-user/に配置されます
5. OpenVPNの構築の実施
5.1. ansibleのインストール
ansibleのインストール方法については以下を参考にして下さい。簡単です。
EC2インスタンスとして構築したAmazonLinux2へAnsibleをインストール(yum)
https://syachiku.net/amazonlinux2-ansible-install/
5.2. ansible-playbookの実行
ansible-playbookを実行してOpenサーバを構築します。 全部で5分くらいかかります。
# ansible-playbook /etc/ansible/site.yml
PLAY [localhost] ***************************************************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
.
(略)
.
RUNNING HANDLER [vpn restart] **************************************************
changed: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=18 changed=17 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
5.3. AWS側設定
AWSインスタンス側で設定変更をします。
- OpenVPNインスタンスの「Source/Dest Check」を「Disabled」に変更する
- ルーティングの設定
5.4. OpenVPNクライアント設定
/home/ec2-user/に配置されている証明書と設定ファイルをPC側にダウンロードします。
サーバ側のPubluc IPアドレスを確認して、設定ファイル(client.ovpn)の接続先を書き換えます。
OpenVPNクライアントのインストールや設定を行います。
https://syachiku.net/ec2openvpn-1/#toc15
5.5. 接続確認
最後にVPNサーバに接続できる事を確認します。
6. まとめ
Ansibleを利用してAmazonLinux2にOpenVPN環境をかなり簡単に構築することができるようになりました。
私は普段はChefを利用していて、今回はじめて本格的にAnsibleを利用してみましたが、chefよりも使いやすいかもしれませんね。
次はせっかくAWSで構築していますので、最後の仕上げとしてCloudFormationと今回のAnsible Playbookを組み合わせてEC2の作成からサーバ構築までを自動化してみたいと思います。
ansibleの学習には以下の書籍を利用しています。かなり分かりやすくてオススメです。
追記
以下の記事で最終的にCloudFormationとAnsibleを組み合わせてみました。
CloudFormationとAnsibleでEC2インスタンス構築時にOpenVPN構築してみた。
https://syachiku.net/cloudformation-ansible-userdata/
AWSを効率的に学習する方法
私が効率的にAWSを学習するために実施した方法は以下の通りです。
①最初に書籍(ハンズオンができる)を購入、座学でAWSの基礎を学習
②AWS資格試験を取得ための学習
※私の場合は①と②を合わせて2か月でソリューションアーキテクトを取得できました。
①AWS基礎学習
最初に購入した書籍は「Amazon Web Services 基礎からのネットワーク&サーバー構築」です。
Amazon Web Services 基礎からのネットワーク&サーバー構築
この本では、AWSの基本サービスを利用したハンズオンを通じて、AWSの基礎を学習することができます。
また、タイトル通りAWSのネットワークやインフラに関しても網羅しているため、もともとインフラ系の技術者ではない人たちにとっても分かりやすい内容だと思います。
とりあえずAWS上にサーバーを設定して開発を行うための準備までするには最良の一冊です。
Amazon Web Services 基礎からのネットワーク&サーバー構築
②AWS資格取得
AWSの基礎をある程度学習することができたら、次はAWS資格を取得しましょう。まずはAWSソリューションアーキテクトを目指しましょう。
資格勉強のための問題集をひたすら解きながら、AWSの知識を積み重ねて習得していきましょう!
苦行ではありますが、この問題集を3周ほどすればAWS用語や構成に関しても習得できているはずです。
今回は以上となります。
コメント