【Project3-5】グローバルIP1つで複数のWebサービスを提供する
2018-04-07
今回困ってた事
自宅サーバの公開用にグローバルIPを取得して運用しています。
しかし、自宅サーバではonwCloud/Zabbix/開発用サーバ等複数のサービスを複数台のサーバを使って運用してます。
サービス毎にNAPTしてこのサービスは、このポートでアクセスという事は非常に手間なのでやりたくないです。
また、公衆無線LANやイベント会場などではネットワーク上のFWが80(http)と443(https)のポートしか通さない設定になってたりするので、いつでもどこからでもはアクセス出来ないので決定的に却下。
ならばサービス毎にグローバルIPを準備する。。。のも問題の解決手法としてはナンセンス。
これらのサービスをインターネット側から、いつでも、どこからでも確認できるようにするのが今回のゴールです。
解決策
ぱっと思いつく手段はリバースプロキシしか無かったので、まずはリバースプロキシで構成します。
これなら、リバースプロキシでグローバルIP宛のhttpとhttpsのパケットを全て受け取り、リバースプロキシで「このホスト名なら、DMZネットワーク内のこのサーバの情報を返す」的な事が出来ます。
また、今回は業務環境で使わないやつを使いたかったのでNginxを使うことに決定。
今回の構成に関わる論理ネットワーク図
ネットワーク構成を図にまとめるとこんな感じになります。
グローバルIPアドレスに着信したHTTP/Sの通信は、DMZネットワーク内のNGINXで構成したリバースプロキシ(ホスト名:iwami35)へNATします。 そして、リバースプロキシへアクセスされたドメイン名に応じて、DMZネットワーク内のサーバへ振分けを行います。
- 例)drive.k636174.netへアクセスしたら192.168.1.229の80へアクセス。
- 例)zabbix.k636174.netへアクセスしたら192.168.1.27へアクセス……etc…etc….
Nginxリバースプロキシ(ホスト名:iwami35)の設定
今回は、素のCentOS7で構成。
[root@iwami35 ~]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
[root@iwami35 ~]#
nginxの設定ファイルは下記のような感じで作成。
[root@iwami35 ~]# ls -alh /etc/nginx/conf.d/
合計 40K
drwxr-xr-x. 2 root root 205 4月 4 16:46 .
drwxr-xr-x. 3 root root 177 3月 23 18:55 ..
-rw-r--r-- 1 root root 833 1月 26 11:57 blog.conf
-rw-r--r-- 1 root root 561 4月 4 16:45 check.conf
-rw-r--r-- 1 root root 1.1K 3月 5 02:07 crystalpi.conf
-rw-r--r-- 1 root root 1.1K 1月 21 21:36 default.conf
-rw-r--r-- 1 root root 990 3月 11 14:31 drive.conf
-rw-r--r-- 1 root root 1.9K 4月 3 19:37 gitbucket.conf
-rw-r--r-- 1 root root 996 1月 24 16:11 iwami_admin.conf
-rw-r--r-- 1 root root 1.1K 1月 24 14:37 redmine.conf
-rw-r--r-- 1 root root 595 3月 23 18:52 search.conf
-rw-r--r-- 1 root root 994 1月 22 13:23 zabbix.conf
[root@iwami35 ~]#
1つの設定ファイルにまとめても良いですが、サブドメイン毎に設定ファイルを分けて管理した方が個人的には便利なので、サブドメイン毎にファイルを作る。 例)zabbix.k636174.netに対するアクセスを処理する設定が記述されるファイル名は【zabbix.conf】にする。
各ファイルの内容(だいたいどのサービスもこんな感じ)
server {
listen 80;
server_name zabbix.k636174.net;
rewrite ^ https://$http_host$request_uri? permanent;
}
server {
listen 443;
server_name zabbix.k636174.net;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
client_max_body_size 2g;
location ^~ /.well-known/acme-challenge/ {
root /usr/share/nginx/html/;
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.1.27/;
proxy_redirect http:// https://;
}
ssl on;
ssl_certificate /etc/letsencrypt/live/zabbix.k636174.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/zabbix.k636174.net/privkey.pem;
}
※全て、zabbix.k636174.net宛の通信のお話なので適時読み替えて下さい。
- 行番号1〜5行目:80番ポートにアクセスしてきた場合の設定
- httpアクセスは問答無用でhttpsへリダイレクトを行う。
- 行番号7〜30行目:443番ポートでアクセスしてきた場合の設定
- 行番号14〜16行目:Let’s Encrypt向けの設定(気が向いたら補足記事書きます)
- 行番号17〜26行目:192.168.1.27にhttpでアクセス
- 行番号27〜29行目:Let’s Encrypt向けの設定(気が向いたら補足記事書きます)
ルーターであるVyOS(ホスト名:hirahata32)の設定
NATの設定(インターネット側からアクセスする際に必要)
必要箇所のみ抜粋。
et nat destination rule 20 destination port 'http,https'
set nat destination rule 20 inbound-interface 'pppoe0'
set nat destination rule 20 protocol 'tcp'
set nat destination rule 20 translation address '192.168.1.35'
解説の必要も不要なぐらいシンプルですが、pppoe0のインターフェイス(グローバルIPが割当たっているインターフェイス)に着信した、httpとhttps(tcp)のパケットは192.168.1.35へNATされる。
DNSの設定(通常利用ネットワークであるVLAN30からのアクセスをするための設定)
必要箇所のみ抜粋
set system static-host-mapping host-name drive.k636174.net inet '192.168.1.32'
set system static-host-mapping host-name gitlab.k636174.net inet '192.168.1.32'
set system static-host-mapping host-name zabbix.k636174.net inet '192.168.1.32'</pre>
DMZとパソコンやスマホを接続するネットワークを分離している。
また、VLAN30のネットワークのプライマリDNSはVyOS(hirahata32)が提供しているのでVyOSに静的マッピングを記述。
3行目を例にすると、zabbix.k636174.netの名前解決するとDMZ内のリバースプロキシのIP(iwami35)のIPアドレスが返される。
なおかつ、VLAN30とDMZはルーティングしてあるので、VLAN30のネットワークからもリバースプロキシ越しに各サービスを利用出来る。