公開中のサーバーを維持しつつv6プラスに移行

前回の記事でUbuntuがアップを始めた…と書いたものの、v6アクセスすると夜のゴールデンタイムのネットワーク速度低下が解消できることがわかり、やってみようかなと考えて申し込み。



光回線ナビ / IPv6対応で速くなる?「IPv6 IPoE + IPv4 over IPv6 接続サービス」って何者?リンク切れ
コムサス / Nifty-V6プラス変更について(IPv6接続オプションではないです)

紆余曲折あったが、関係先のみなさんが親切にしてくれたおかげで開通!だが、v6プラス契約の場合、IPv6のアドレスで公開できるポートが限られる。いわゆるウェルノウンポートは使用できないのだが、ルーターつないじゃったよ速度が早くなっちゃったよ後戻りはできないよ、どーすんの俺?と、長く暗いトンネルの入り口に立ったのだった…

 

できあがった環境

結論から。

  • v6プラス契約でゴールデンタイムでも90Mbpsを超える通信が可能になった(Googleのスピードテスト)。
  • PPPoE接続でIPv4のアドレスが得られたことで、従来通り各種サービスをインターネットに向けて公開できた。
    ゴールデンタイムの場合でも、「インターネット側からの要求」は5~20Mbps程度であるものの、「インターネットへの応答」は90Mbps程度あるかもしれない。※

※かもしれないと書いたのは、相手がv6プラスみたいなサービスでアクセスしてくれば早そうだという予測から。計測してみると、IPv4のPPPoEは下りは遅くなるけれど、上りは高速。

ネットワーク構成は以下の通り。物理と論理がちょっと違っている。実はウチはClass Bのアドレス体系でネットワークを運用している。

     [ Internet ] 物理構成図
          │
      ┌─┴─┐
      │ ONU  │
      └─┬─┘
┌────┴────┐
│Router(1)         │
│IP: 172.16.1.1/16 │
└────┬────┘
      ┌─┴─┐                                                ┌──────┐
      │ HUB  ├──────────────────────┬─┤ WiFi Bridge├─┬─── ・・・
      └─┬─┘                                            │  └──────┘  │
┌────┼──────────────────┐┌────┴────┐┌────┴────┐
│        │                         VMware ESXi││Main PC           ││Android Phone     │
│     (Bridge)                                 ││IP: 172.16.1.2/16 ││IP: 172.16.1.3/16 │
│        ├───────────┐            ││GW: 172.16.1.1    │└─────────┘
│┌───┴─────┐┌────┴─────┐││NS: 172.16.1.100  │
││Router(2)         ││Server              ││└─────────┘
││IP: 172.16.2.1/16 ││IP: 172.16.1.100/16 ││
││GW: 172.16.2.1    ││GW: 172.16.2.1      ││
││PPPoE Connection  ││NS: 172.16.2.1      ││
│└─────────┘└──────────┘│
└───────────────────────┘

 

論理的には、サーバーはRouter(2)の下に入って別ネットワークを構成する形になる。

論理的には別ネットワークだが、物理的に1つのネットワーク上にあるとMain PCからServerに問題なくアクセスができる。同じ172.16.0.0/16のセグメントにいることがポイントである(もちろん、192.168.nnn.0/24のネットワーク体系でも同じセグメントならOK)。

このことをとある有力な技術者から教えてもらったことで、今回の結論を導き出すことができた。超感謝。

もしも別のセグメントにしていたら、サーバー側にかなりの変更が必要にり、ひょっとすると未だにサービス復旧できていなかったかもしれない。

 

ネットワークの経路は、

  • MainPCやAndroid Phoneは、Router(1)を通ってIPv4 over IPv6、ないしは、IPv6 IPoEでインターネットに接続。[高速]
  • ServerはRouter(2)のPPPoE接続を通ってインターネットに接続する。[低速]

となる。[低速]とは書いたものの、昼間はv6プラスと同じとは言わないがかなりの速度が出る。あくまでもゴールデンタイムについてのイメージ記述。

 

このネットワーク構成にすることにより以下のメリットがある。

  • Serverの設定はゲートウェイの変更のみ。これだけでPPPoE接続を通ったインターネットアクセス(従来通り)ができる上に、ネットワーク上の他の端末からも問題なくアクセスができる。
  • LAN内の他の端末は設定を変更する必要がない。

得られた結果に満足!

 

環境構築

結構な勢いでやることがある。

 

貸与されたルーターの設定変更

図で言うところの Router(1) の設定変更。

PPPoEブリッジをONにする。

→ 今回NTTから貸与されたルーターはデフォルトでONだったと思う。

これにより、Router(1) 配下に設置予定の Router(2) が PPPoE 接続できるようになる。

 

ルーターの構築

図で言うところの Router(2) の構築。

結果からすると、ブロードバンドルータを1つ追加で購入するのが一番簡単な気がする。しかし、Ubuntuでルーターを組んじゃえばいいんじゃね?と思ってしまったがために、ちょっと大変なことになった。

ルーターにするOSとして Ubuntu 18.04 Server を選定。理由は使い慣れているから、ということだけなので新しいものならなんでも大丈夫なんじゃないかと思う。メモリは最低要件の512MBとしたが、設定完了後もメモリが余りまくっているので問題なさそう。

 

IPv6無効化

インストールは過去記事ベースで行う。このルーターは従来のIPv4によるサービス公開のために構築するのだから、IPv6は無効化する。IPv6接続はRouter(1)に任せておけば良い。

ついでに、起動時の待ち時間が発生しないようにタイムアウト時間も1秒に変更。

/etc/default/grub
#GRUB_TIMEOUT=10
GRUB_TIMEOUT=1
#GRUB_CMDLINE_LINUX=""
GRUB_CMDLINE_LINUX="ipv6.disable=1"

 

反映。

$ sudo update-grub

 

インストール後にアップデートやパッケージのインストールをするので、インターネットに接続できなきゃならない。よって、セットアップ時にIPアドレスは設定せずServerが提供するDHCPサービスを利用し、ルーター化する準備ができてからIPアドレスを変えていく。

 

PPPoE接続ができるようにする

具体的なコマンドは以下。

$ sudo apt update; sudo apt dist-upgrade; sudo apt autoremove
$ sudo apt install pppoeconf

 

ここで、pppoeconfを使ってPPPoE接続の設定情報を作る。

$ sudo pppoeconf ← これでインストール画面になる

 

pppoeconfの設定は以下の回答で進めた。

  • POPULAR OPTIONS

    → Yes

  • ENTER USERNAME

    → 以前使っていたブロードバンドルーターに設定していたユーザー名。

  • ENTER PASSWORD

    → 同パスワード

  • USE PEER DNS

    → Yes

  • LIMITED MSS PROBLEM

    → Yes

  • DONE(ブート時に接続を開始するかどうか聞かれている)

    → Yes

  • ESTABLISH A CONNECTION

    → Yes

  • CONNECTION INITIATED

    → Ok

結果を確かめてみる。

$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 172.16.1.nnn/16 brd 172.16.255.255 scope global ens160
       valid_lft forever preferred_lft forever
5: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1454 qdisc fq_codel state UNKNOWN group default qlen 3
    link/ppp
    inet nnn.nnn.nnn.nnn peer nnn.nnn.nnn.nnn/32 scope global ppp0
       valid_lft forever preferred_lft forever

 

pppoeconfによりPPPoE接続ができるようになったから、LANのインターフェースになっているens160の設定を変える。

/etc/netplan/50-cloud-init.yaml
# This file is generated from information provided by
# the datasource.  Changes to it will not persist across an instance.
# To disable cloud-init's network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        ens160:
            addresses:
            - 172.16.2.1/16 ← Router(2)の計画に合わせて変更
            dhcp4: false
            gateway4: 172.16.2.1 ← Router(2)はGWでもある
            nameservers:
                addresses:
                - 8.8.8.8 ← 実際にはPPPoE開始時にresolv.confが書き換えられるので何でも良いように思われる
                search: []
    version: 2

 

変更を反映して確認する。

$ sudo netplan apply
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 172.16.2.1/16 brd 172.16.255.255 scope global ens160
       valid_lft forever preferred_lft forever
5: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1454 qdisc fq_codel state UNKNOWN group default qlen 3
    link/ppp
    inet nnn.nnn.nnn.nnn peer nnn.nnn.nnn.nnn/32 scope global ppp0
       valid_lft forever preferred_lft forever

 

ここまでで、Router(2)はインターネットに接続できて、172.16.0.0/16とも接続できるようになった。

ちなみに、pppを接続したり切断したりするコマンドは以下。

$ sudo pon dsl-provider
$ sudo poff dsl-provider

 

 

ルーティング設定

ここからルーターとして動作するように設定していく。

まず、カーネルパラメーターを変更し、パケット転送をオンにする。

/etc/sysctl.conf
net.ipv4.ip_forward = 1

--- 攻撃回避メモ(以下は最初から1になっているので設定不要だった)
net.ipv4.tcp_syncookies=1
net.ipv4.icmp_echo_ignore_broadcasts=1

 

反映。

$ sudo sysctl -p

 

次に、転送の仕方を書く。今まで ufw を使うなどしてどうにか避け続けてきた iptables だ…。ファイルはどこに作ってもいいと思うんだけど、今回はここに作って実行して直して実行して…を繰り返した。

※危険な設定があれば教えてください…

/root/iptable-settings
#!/bin/sh ← テストを繰り返すにはスクリプトにしたほうが楽チンだった

readonly   thishost='172.16.2.1'
readonly  localarea='172.16.0.0/16'

readonly  myserver1='172.16.1.100'
readonly  myserver2='172.16.1.101' ← 別IPアドレスで公開しているサーバーがあるので書いている

readonly        any='0.0.0.0/0'

readonly  local_nic='ens160'
readonly global_nic='ppp0'


#-------------------------------------------------------------------------------
# Initialize
#-------------------------------------------------------------------------------

# Initialize
iptables -F        ← デフォルトテーブルのチェインを初期化
iptables -t nat -F ← natテーブルのチェインを初期化
iptables -X        ← デフォルトテーブルの組み込み以外のチェインを削除
iptables -Z        ← 全てのチェインのパケットカウンタとバイトカウンタをゼロに
iptables -P INPUT   ACCEPT
iptables -P OUTPUT  ACCEPT
iptables -P FORWARD ACCEPT

iptables -N LOGGING_I ← ログ用のチェーンを先に作っておく
iptables -N LOGGING_F
iptables -N LOGGING_O

# Policy
iptables -P INPUT DROP ← 基本、入力を拒否。ただし、接続済み、あるいはそれに関連するものは許可。
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -P OUTPUT ACCEPT ← 基本、出力を許可。ただし、ローカルパケットが外に出ようとしたら拒否。
iptables -A OUTPUT -o $global_nic -d 10.0.0.0/8     -j LOGGING_O ← LOGGING_Oチェーンに遷移させてDROP。
iptables -A OUTPUT -o $global_nic -d 176.16.0.0/12  -j LOGGING_O
iptables -A OUTPUT -o $global_nic -d 192.168.0.0/16 -j LOGGING_O
iptables -A OUTPUT -o $global_nic -d 127.0.0.0/8    -j LOGGING_O

iptables -P FORWARD DROP ← 基本、転送を拒否。ただし、ローカルから外に出るものはポート135,137:139,445を除いて許可。接続済み、あるいはそれに関連するものは許可。
iptables -A FORWARD -p tcp -i $local_nic -o $global_nic -m multiport --dports 135,137:139,445 -j DROP
iptables -A FORWARD -p udp -i $local_nic -o $global_nic -m multiport --dports 135,137:139,445 -j DROP
iptables -A FORWARD -i $local_nic -o $global_nic -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

# Loopback
iptables -A INPUT  -i lo -j ACCEPT ← ループバックはすべて許可。
iptables -A OUTPUT -o lo -j ACCEPT


#-------------------------------------------------------------------------------
# Router setting
#-------------------------------------------------------------------------------
iptables -t nat -A POSTROUTING -s $localarea -o $global_nic -j MASQUERADE ← ローカルから外に出るものはマスカレード。


#-------------------------------------------------------------------------------
# Local area network setting
#-------------------------------------------------------------------------------

### DNS
iptables -A INPUT -p udp -i $local_nic -d $thishost --dport 53 -j ACCEPT ← 主にServer(内向きDNSとして稼働)からの問い合わせを受け付ける。

### ICMP
iptables  -A INPUT  -p icmp --icmp-type echo-request -i $global_nic -j ACCEPT -m comment --comment 'ICMP(grobal)'
iptables  -A INPUT  -p icmp --icmp-type echo-reply   -i $global_nic -j ACCEPT -m comment --comment 'ICMP(grobal)'
#iptables -A OUTPUT -p icmp --icmp-type echo-reply   -o $global_nic -j ACCEPT -m comment --comment 'ICMP(grobal)' ← 書き方を忘れないためのメモ
#iptables -A OUTPUT -p icmp --icmp-type echo-request -o $global_nic -j ACCEPT -m comment --comment 'ICMP(grobal)' ← 書き方を忘れないためのメモ
iptables  -A INPUT  -p icmp -i $local_nic -j ACCEPT -m comment --comment 'ICMP(all-ok, local)'
#iptables -A OUTPUT -p icmp -o $local_nic -j ACCEPT -m comment --comment 'ICMP(all-ok, local)' ← 書き方を忘れないためのメモ

### IGMP(この経路でこの接続をするのか微妙なところ)
#iptables -A INPUT  -p igmp -j ACCEPT
#iptables -A OUTPUT -p igmp -j ACCEPT

### SSH
iptables -A INPUT -p tcp -i $local_nic -d $thishost --dport 22 -j ACCEPT


#-------------------------------------------------------------------------------
# Listen on wide area network setting
#-------------------------------------------------------------------------------

### HTTPS
iptables -t nat -A PREROUTING -p tcp -i $global_nic -d $any       --dport 443   -j DNAT --to-destination $myserver1:443
iptables        -A FORWARD    -p tcp -i $global_nic -d $myserver1 --dport 443   -j ACCEPT

### HTTP
iptables -t nat -A PREROUTING -p tcp -i $global_nic -d $any       --dport 80    -j DNAT --to-destination $myserver1
iptables        -A FORWARD    -p tcp -i $global_nic -d $myserver1 --dport 80    -j ACCEPT

### SMTP
iptables -t nat -A PREROUTING -p tcp -i $global_nic -d $any       --dport 25    -j DNAT --to-destination $myserver1
iptables        -A FORWARD    -p tcp -i $global_nic -d $myserver1 --dport 25    -j ACCEPT

### HTTP(Server2)
iptables -t nat -A PREROUTING -p tcp -i $global_nic -d $any       --dport 18080 -j DNAT --to-destination $myserver2
iptables        -A FORWARD    -p tcp -i $global_nic -d $myserver2 --dport 18080 -j ACCEPT

### RTMP(Adobe Systems Flash Time Messaging Protocol)
iptables -t nat -A PREROUTING -p tcp -i $global_nic -d $any       --dport 1935  -j DNAT --to-destination $myserver1
iptables        -A FORWARD    -p tcp -i $global_nic -d $myserver1 --dport 1935  -j ACCEPT

### L2TP
iptables -t nat -A PREROUTING -p udp -i $global_nic -d $any       --dport 1701  -j DNAT --to-destination $myserver1
iptables        -A FORWARD    -p udp -i $global_nic -d $myserver1 --dport 1701  -j ACCEPT

### ISAKMP
iptables -t nat -A PREROUTING -p udp -i $global_nic -d $any       --dport 500   -j DNAT --to-destination $myserver1
iptables        -A FORWARD    -p udp -i $global_nic -d $myserver1 --dport 500   -j ACCEPT

### IPSec NAT Traversal
iptables -t nat -A PREROUTING -p udp -i $global_nic -d $any       --dport 4500  -j DNAT --to-destination $myserver1
iptables        -A FORWARD    -p udp -i $global_nic -d $myserver1 --dport 4500  -j ACCEPT


#-------------------------------------------------------------------------------
# Diffender
#------------------------------------------------------------------------------- 
# 攻撃に対する対策を入れるならここ


#-------------------------------------------------------------------------------
# Logging
#-------------------------------------------------------------------------------

iptables -A LOGGING_I -j LOG --log-level warning --log-prefix "[IPT BLOCK I] " -m limit ← 本番
#iptables -A LOGGING_I -j LOG --log-level warning --log-prefix "[IPT BLOCK I] " ← デバッグ中はこちらの方がチェックしやすい
iptables -A LOGGING_I -j DROP
iptables -A INPUT -j LOGGING_I

iptables -A LOGGING_F -j LOG --log-level warning --log-prefix "[IPT BLOCK F] " -m limit
#iptables -A LOGGING_F -j LOG --log-level warning --log-prefix "[IPT BLOCK F] "
iptables -A LOGGING_F -j DROP
iptables -A FORWARD -j LOGGING_F

iptables -A LOGGING_O -j LOG --log-level warning --log-prefix "[IPT BLOCK O] " -m limit
#iptables -A LOGGING_O -j LOG --log-level warning --log-prefix "[IPT BLOCK O] "
iptables -A LOGGING_O -j DROP
#iptables -A OUTPUT -j LOGGING_O ← ここまできたものはデフォルトポリシーで通過

 

作成にあたっては、以下で勉強をさせていただいた。

@IT / 習うより慣れろ! iptablesテンプレート集
Qiita / Ubuntu 16.04 でルータつくる
Nibelungen Code / iptablesでログを取る
ディーネット / iptablesにコメントを加えてみよう

この設定に加えて、以下で晒されている(!)攻撃に対する対策を組み込む。
対策部分はほとんどコピー&ペーストで追加できると思う。矛盾はない。実際に攻撃してみていないが、それはまた余裕が出てきたらやってみよう。
Qiita / 俺史上最強のiptablesをさらす

 

このスクリプトを実行し、/var/log/syslogに出力されるログで動作を確認。

プロトコル番号の一覧はこちら。
Wikipedia / プロトコル番号一覧

パケットがどこまで飛んだか確認するのはこちら。
Qiita / 超絶初心者むけtcpdumpの使い方

 

設定を恒久化

スクリプトで作った設定は再起動すると消えてしまう。

できあがった設定を恒久化させる必要がある。

Qiita / Ubuntu 16.04 iptables設定(基礎知識)

/etc/network/if-pre-up.d/にスクリプトを保存しておくと、ネットワーク接続が確立する寸前に実行してくれるので、そこでiptablesの設定を復元する、ということの模様。

/etc/network/if-pre-up.d/iptables-settings を新規作成。
#!/bin/sh
/sbin/iptables-restore < /etc/network/iptables.rules
exit 0

※パーミッションは755に。

iptables.rules を作成。

$ sudo iptables-save | sudo tee /etc/network/iptables.rules

 

再起動して確かめる。

 

DynamicDNSサービスへの通知

起動時、PPPoEのセッションが確立したらDynamicDNSサービスに通知がしたい。

使わせていただいているDynamicDNSはメールサーバーにアクセスすることでIPアドレスを通知できるようになっている。通知にはbiffpopが便利なので使わせていただいている。

従来は、Router(1)が何らかの理由で再起動するとIPアドレスが変わってしまうが、それを検知する方法もない…ということで、20分毎に通知をしていた(スミマセン)。

今後はPPPoEのセッションが確立したときに通知が送られるようにすれば良い。

/etc/ppp/ip-up.d/9ddns
#!/bin/sh
/etc/ppp/biffpop -s -c /etc/ppp/.biffpoprc
exit 0

※パーミッションは755に。

また、cronによる通知はDynamicDNSサービスのルールから考えて、日に1回で十分なので修正しておく。

 

ログの出力先を変える

こんなにサクッとできるものなのね…知識があるって大事だなぁ。

HACKnOTE / iptablesでdropしたパケットのログの出力先を変える
into the void / syslogの使い方をあらためて整理してみた

ログをiptables.logというところにだけ出すようにする。

/etc/rsyslog.d/30-iptables.conf を新規作成(UFWのをそのまま利用)。
# Log kernel generated UFW log messages to file
:msg,contains,"[IPT " /var/log/iptables.log

# Uncomment the following to stop logging anything that matches the last rule.
# Doing this will stop logging kernel generated UFW log messages to the file
# normally containing kern.* messages (eg, /var/log/kern.log)
& stop ← これにより、syslogにログが出力されなくなる。とても助かる。

 

反映。

$ sudo systemctl restart rsyslog.service

 

ついでに、ログローテーションができるようにしておこう。

/etc/logrotate.d/iptables を新規作成(UFWのをそのまま利用)。
/var/log/iptables.log
{
    rotate 54 ← 1年くらい前まで遡ることができれば大丈夫だろうと安易に設定
    weekly
    missingok
    notifempty
    compress
    delaycompress
    sharedscripts
    postrotate
        invoke-rc.d rsyslog rotate >/dev/null 2>&1 || true
    endscript
}

 

こちらは、ファイルを作っておけば良く、cron → /etc/cron.daily で日々呼び出される模様。

こんなに簡単に切り分けできるのね…びっくり。

 

サーバーの起動順序を変える

ESXi の設定を見直し、Router(2) → Server の順で起動するように変える。

停電→起動!ってなときに、Router(2)が先に起動してPPPoE接続を確立して待ち受け、Serverが起動してウチのネットワークが動き始める…というシナリオだ。

 

以上で設定完了。

 

起こったこと

貸与されたルーターの静的マスカレード設定が消える…

新しく貸与されたルータを繋いでIPv4の「静的マスカレード設定」を進めていく…で、テストするとうまく行かなくて、もう一度ルーターの設定画面を見に行くと「静的マスカレード設定」の項目がなくなっている。

おかしいな…出荷時状態に戻してもう一回、もう一回と繰り返したが、「静的マスカレード設定」の項目が途中でなくなっちゃう。URLを覚えておいてアクセスしても怒られる。何だこれ?

Qiita / IPv6プラス環境におけるIPv4ポート公開設定
NORIのブログ / v6プラスを使ってみよう その1

これを見たら…うーん、なるほど、設定項目は消えるようになっているのね、ウェルノウンポートでサービス公開ができないのね、と理解。同時に[本当に]目の前が暗くなった。

でも、解決策はあって、ルーターがもう1つ必要なのね、とわかった。

疲労コンパイル / v6プラスとIPv4(PPPoE)を併用する(その1)

ルーターは実はあるのだけれど、Wifiルーターなので設置場所が結構重要で動かせない。

じゃあ、線を増やす方法は?と考えたけれども配線工事が必要で大掛かりすぎる。

じゃあ、Linuxで作るか、あぁ、ルーティングか、iptablesか…と茨の道が見えてきたのだった。

 

sudoでホスト名が解決できない

sudoでコマンド実行時にエラーメッセージが表示された。

$ sudo ls
sudo: unable to resolve host router2

 

/etc/hosts にホスト名を追記して解決。
127.0.0.1       localhost.localdomain   localhost
::1             localhost6.localdomain6 localhost6
127.0.0.1       router2

# The following lines are desirable for IPv6 capable hosts
::1             localhost ip6-localhost ip6-loopback
fe00::0         ip6-localnet
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters
ff02::3         ip6-allhosts

 

 

IPv6でのサービス提供 ※未解決

そうだ、IPv6でサービス提供できればいいんじゃね?と一瞬考えた。

利用させていただいている Dynamic DNS サービスはPOP3アクセスでIPを通知するようになっているので、IPv6のアドレスを通知すりゃいいんじゃないの?と。

サーバーはUbuntu 12からアップグレードし続けて運用中。IPv6のIPアドレスは以下で追加・削除ができた。

Quitta / 初歩のipコマンドの使い方(Link、IPアドレス)

/etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 172.16.1.100
netmask 255.255.0.0
gateway 172.16.1.1
dns-domain hogeserver.hogeddns.jp
dns-nameservers 172.16.1.1
iface eth0 inet6 manual
 up   ip -6 addr add xxxx:xxxx:xxxx:xxxx::100/64 dev $IFACE
 down ip -6 addr del xxxx:xxxx:xxxx:xxxx::100/64 dev $IFACE

auto eth0:1
iface eth0:1 inet static
address 172.16.1.101
netmask 255.255.0.0
gateway 172.16.1.1
dns-nameservers 127.0.0.1

 

反映。

$ sudo systemctl restart networking

※たまに、何度やってもどうにも変更ができなくなることがあった。この場合は再起動…

で、通知にはbiffpopを利用させていただいているのだが、何度やってもIPv4でアクセスしている。なんでだろと調べ直してみたら…

ナカタの Digital Wonder Land / POP3/APOP によるメイルチェッカー IPv6 対応

以前、コンパイルする際にはIPv6を無効化していたので、それでもコンパイルできる方法で作っていた模様。結果、IPv6アクセス部分が含まれていなかった。

改めてコンパイルしたら、IPv6でアドレスを通知するようになった!

※しかし、今度はサーバーのIPv6アドレスを思い通りにコントロールできず、この方向の検討は中断。別途。

 

Router(2)を別セグメントに配置 ※未解決

Router(2)に別セグメントのIPアドレスを振った。具体的には192.168.1.1を。さらに、Serverに192.168.1.100のアドレスを振った。

ルーティングやIPテーブルに関して調べて調べて試して試して…どうにかローカルにおいた192.168.1.2のテストマシンからApache→Wordpressにアクセスしたらエラーが出た。

設定が自ホストのIPじゃないよ、と。

これはきっとServerに192.168.1.100のアドレスを振るんじゃなくてルーティングすりゃ良さそうだとは思ったものの、iptables の暗中模索が続き、サーバーが停止し続けていたで断念。

 

Apacheが外に向かって何かを投げてる… ※未解決

なんだか不思議なログが…

Nov 11 05:59:46 router2 kernel: [55808.580792] [IPT BLOCK I] IN=ens160 OUT= MAC=xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx SRC=172.16.1.100 DST=<ppp0のIPアドレス> LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=21957 DF PROTO=TCP SPT=44988 DPT=443 WINDOW=29200 RES=0x00 SYN URGP=0

※最初はなぜFORWARDしないの?と思ったのだが、宛先がppp0のアドレスなのでINPUTだった。

送ってきているのはサーバーなので、誰が?と、このログが出るタイミングを見計らって以下を実行。

$ sudo lsof -i

 

結果、以下の表示が…

apache2   4561  www-data   28u  IPv4  39998      0t0  TCP 172.16.1.100:44988-><Router2のpppのホスト名>:https (SYN_SENT)
apache2   4564  www-data   26u  IPv6  35273      0t0  TCP 172.16.1.100:https->172.16.1.nnn:51851 (ESTABLISHED)

 

そもそも、宅内ネットワークはIPv4とIPv6のデュアルスタックになったので内向きDNSはIPv6対応させたいが、ApacheはIPv6で動いて欲しくない。

Qiita / Apache httpd IPv4のみで通信

これに従って、現在有効なサイト設定のVirtual Hostをすべて書き換えた。

#<VirtualHost *:443>
<VirtualHost 0.0.0.0:443>

 

だけど、IPv6なのは変わらず。これはApacheの仕様の模様。

そしてHTTPSに対してこんな要求が飛ぶのはなぜ?ということでモジュールを見てみたら、なんだかウチでは使っていないはずのものが動いてるぞ…

$ sudo a2dismod proxy_balancer
$ sudo a2dismod proxy_ftp
$ sudo systemctl restart apache2.service

 

使ってなさそうなモジュールを止めてみたものの、それでも止まらなかった。

ただ、特段問題が起きているようにも見えないので放っておくことにした。

 

OUTPUTのパケットがドロップする

なんだか知らないがOUTPUTのパケットがドロップする。おかしいな…

元々は、こんなのを /root/iptable-settings に書いていた。

iptables -P INPUT   DROP
iptables -P OUTPUT  ACCEPT
iptables -P FORWARD DROP
・・・
iptables -N LOGGING
iptables -A LOGGING -j LOG --log-level warning --log-prefix "DROP:" -m limit
iptables -A LOGGING -j DROP
iptables -A INPUT   -j LOGGING
iptables -A OUTPUT  -j LOGGING
iptables -A FORWARD -j LOGGING

 

デフォルトポリシーがACCEPTなんだから、OUTPUTは基本許されるんだろうと思っていた。

ところが…実際には、設定した色々な評価をすり抜けてここに到達したとき、

iptables -A OUTPUT -j LOGGING

の記述によって出力パケットはLOGGINGチェーンに遷移し、そこでログを出力した後にDROPされてしまうのだった。

これ、参照元のテンプレートでは適切に処理したり、赤文字行を含まない形のテンプレートにしたりして問題がないように整理されていたのだが、その事に気づいたのは学習から7日後のことだった(5日後にサービスをとりあえず復旧したときにはOUTPUTを書いてどうにか動かしていた)。

デフォルトチェーンを通過

 → 最後に赤文字行で無条件にLOGGINGチェーンに遷移

  → 無条件ドロップ

結局、このiptablesの設定はデフォルトポリシーがどんなものであれ、ACCEPTされなかったパケットは結果的にLOGGINGチェーンに遷移し、必ずドロップするのだ。

本編で書いた設定は、「ACCEPTとFORWARDはそもそもデフォルトポリシーがDROPなんだから、LOGGINGチェーンに落ちてドロップしても構わない」訳なので、最後まできたところでLOGGINGチェーンに落として無条件DROPさせることにした。

一方で、OUTPUTはデフォルトポリシーがACCEPTなので問題のあるパケットをLOGGINGチェーンに落としてDROPさせ、問題のないパケットはスルーすることでデフォルトポリシーのACCEPTと判断される設定にした。

これで、DROPしたパケットはすべてログに出力される理想的な状態になった。

 

 

さいごに

以上で2つ目のルーターが稼働し、従来通りにサービスを提供することができるようになった。

 

契約変更に伴ってルーターが金曜日の夜に届き、土曜日の午前中に設置…その時点から提供していたサービスが停止し、水曜深夜まで再開することができなかった。ここまでサービス停止が長引いたのは初めてではなかったか。準備不足であった感は否めない。

ん?じゃあ、準備していればできたの?といえば、それがそうでもなくて、まず、iptablesは避けて通ってきたし、IPv6もかじったけど理解できる前に終わってる。そう、困らなきゃ本気にならないし、本気にならないと覚えないという性格なだけに、困った状況を作り出して一気にそれを解決する必要があったのだ。

今にして思えば、古いルーターにもPPPoEブリッジ機能はあったんだから、契約を申し込む前にUbuntuルーターを構築することもできたし、ルーターが届いたからと言ってIPv6接続にこだわらずIPv4接続だけに切り替えてサービスを提供しながらUbuntuルーターを構築することもできた。自信がなければルーターを買ってくるという手もあった。でも、それは今だから思えることであって、暗中模索であってもできるまで突っ走っる性格なんだぜ~。

ということで、やっぱ必然で、避けられなくて、やるしかなかったのですよ。

 

結果として、iptablesが少しわかり、Ethernetってものが少しわかり、IPv6もわかってきた。

そして、あの有力な技術者の知識は半端じゃねぇということが良くわかった。ネットワークに関する様々な問題に対応しようとするとき、彼が頼りになる仲間であることを再認識できたことは最高だった。

いいことあるじゃん!あるじゃん!すごくあったじゃん!

さぁ、明日からも頑張っていこう!

お気軽にどうぞ ~ 投稿に関するご意見・感想・他

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です