VLANタグを使ってルータを構築

TV BOX(amlogic s905x)は普段使っているルータに比べて性能は格段に優れているのですが、LANポートが1つしかなくてネットワーク機器には不向きです。一方でルータは十分なLANポートをもっているがCPUスペックが低いです。そのためサービスが多くなるに従って動作が重くなり肝心のネットワークのスループットに影響が出てしまします。実際、IKEv2を使っていてルーターのネットワークのスピードの低下の影響はかなり大きいです。そこでTV BOXにarmbianを入れてルータにしてしまおうというのが今回の趣旨です。

OpenWrt

OpenWrt

Armbian

Armbian

今年の夏にカーネル5.1のarmbianが出て、動かしてみるとかなり実用的であることがわかりました。それでcacti等を動かしていたのですが、まだまだパワーが余っています。ルータのタスクを一部移そうかと検討してたのですが、どうせならルータ化した方が話が早いという結論になりました。LANポートが1つしかないので、VLANタグを付けて、すなわちVLAN多重化してネットワークを分けます。そして旧ルータのVLAN機能のあるHUBと組み合わせて使います。VLAN機能によってかなり自由度の高いネットワークの設計ができます。自分専用のサーバのみならず、DMZを作ってインターネット用にサーバを立てることもできます。

ただし注意することはTV BOXはあくまでもマルチメディア再生機なのでネットワーク部分が弱いです。LANポートは100Mbpsしかないので、コンテナで複数サーバを立てるとネットワークがボトルネックになる可能性があります。ラズパイなどのSoCボードならその点は優れているのですが、熱暴走しないとかシステムの安定性となると製品化された方に優位性があります。それぞれ一長一短があるので使う人次第ということになります。さらにストレージがeMMCなのでHDDやSSDより性能が劣ります。

OpenWrt(旧ルーター)の設定

Vlanのタグをつかってセグメントを分けます。さらにInterfaceとZoneをつくります。

Network>Switch

Network>Interfaces

Network>Firewall

Armbian(新ルータ)の設定

Debian旧来のネットワークの設定をします。一部vlanができないのでブリッジを使ってインターフェースを作りました。

LAN Networkの設定

# source /etc/network/interfaces.d/*
# Network is managed by Network manager
auto lo
iface lo inet loopback

#auto eth0
iface eth0 inet manual

iface eth0.111 inet manual
  vlan-raw-device eth0

iface eth0.333 inet manual
  vlan-raw-device eth0

iface eth0.999 inet manual
  vlan-raw-device eth0

auto br0.111
iface br0.111 inet static
  bridge_ports eth0.111
  address 192.168.1.10
  netmask 255.255.255.0
  broadcast 192.168.1.255
  network 192.168.1.0
  bridge_maxwait 0
  bridge_fd 0
  #bridge_hello 2
  #bridge_maxage 12
  bridge_stp off

auto br0.333
iface br0.333 inet static
  vlan-raw-device eth0
  bridge_ports eth0.333
  address 192.168.10.129
  netmask 255.255.255.128
  broadcast 192.168.10.255
  network 192.168.10.128
  bridge_maxwait 0
  bridge_fd 0
  bridge_stp off

#auto br0.666
#iface br0.666 inet static
auto eth0.666
iface eth0.666 inet static
  vlan-raw-device eth0
  #bridge_ports eth0.666
  address 192.168.10.10
  netmask 255.255.255.128
  broadcast 192.168.10.127
  network 192.168.10.0
  #bridge_maxwait 0
  #bridge_fd 0
  #bridge_stp off

auto wan.999
iface wan.999 inet ppp
  bridge_ports eth0.999
  bridge_maxwait 0
  bridge_fd 0
  bridge_stp off
  

 DSLの設定

ppp関連のパッケージをインストールします。pppoeconfでの設定がオススメですが、直接設定ファイルを編集しても可能です。私の使っているDSLサービスはchapが使えなかったので一部設定を変えています。

/etc/systemd/system/pppoe.service

[Unit]
 Description=PPPoE connection
 [Service]
 Type=oneshot
 RemainAfterExit=true
 ExecStart=/usr/bin/pon dsl-provider
 ExecStop=/usr/bin/poff -a dsl-provider
 [Install]
 WantedBy=default.target

/etc/ppp/pap-secrets

"myname@xxx.so-net.ne.jp" * "mypass"

/etc/ppp/chap-secrets: ISP so-netはなし

/etc/ppp/peers/dsl-provider

noipdefault
 usepeerdns
 defaultroute
 hide-password
 lcp-echo-interval 20
 lcp-echo-failure 3
 connect /bin/true
 noauth
 persist
 mtu 1492
 noaccomp
 default-asyncmap
 plugin rp-pppoe.so
 nic-wan.999
 user "myname@xxxx.so-net.ne.jp"

DDNSの設定

mydns.jpを使っているのですが、OpenWrtと違ってDebianには自動更新するパッケージがありません。そこでsystemdを使って自作します。

/etc/systemd/system/ddns-update.service

[Unit]
 Description=DDNS update
 After=network.target
[Service]
 Type=simple
 User=root
 Restart=always
 WorkingDirectory=/etc/ddns
 ExecStart=/etc/ddns/ddns-update.sh start
 ExecStop=/etc/ddns/ddns-update.sh stop
 StandardOutput=journal
 StandardError=journal
[Install]
 WantedBy=multi-user.target

/etc/ddns/ddns-update.sh

#!/bin/sh

HOST=oreore.mydns.jp

start() {
  while true; do
    MY_IP=`ip addr show ppp0 | awk '/inet/ {print $2}' | cut -f1 -d "/"`
    DDNS_IP=`dig @8.8.8.8 $HOST type=A +short`
    if [ "$MY_IP" != "$DDNS_IP" ]; then
        /etc/ddns/oreore.mydns.jp.sh >/dev/null 2>&1
    fi
    sleep 1
  done
}

stop() {
    kill -KILL `pgrep -f -a ddns-update.sh | awk '{print $1}'`
}

case $1 in
  start|stop) "$1" ;;
esac

cat /etc/ddns/oreore.mydns.jp.sh

#!/bin/sh

IP=`ip addr show ppp0 | awk '/inet/ {print $2}' | cut -f1 -d "/"`
curl -s "https://www.mydns.jp/directip.html?MID=mydnsxxxxxxxx&PWD=xxxxxxxxxxxxxxxxxxxxxxx&IPV4ADDR=$IP"
exit 0

Firewallの設定

私はShorewallをいうfirewallプログラムを使っているので旧ルーターのOpenWrtの設定に合わせて変更します。

/etc/shorewall/interfaces

?FORMAT 2
###############################################################################
#ZONE		INTERFACE		OPTIONS
net             ppp+                     
loc             br0.111                 routeback,bridge,dhcp,tcpflags,logmartians,nosmurfs,sourceroute=0
dmz             br0.333                 routeback,bridge,dhcp,tcpflags,logmartians,nosmurfs,sourceroute=0
tor             eth0.666                dhcp,tcpflags,logmartians,nosmurfs,sourceroute=0
vpn0            tun+

/etc/shorewall/policy

###############################################################################
#SOURCE		DEST		POLICY	LOGLEVEL	RATE	CONNLIMIT
$FW		net		ACCEPT
$FW		loc		ACCEPT
net		all		DROP		info

# loc
loc             $FW             DROP
loc             net             ACCEPT

# dmz
dmz             $FW             DROP
dmz             net             ACCEPT

# tor
tor             $FW             DROP
tor             net             ACCEPT

## vpn0: openvpn
vpn0		loc		ACCEPT
vpn0		$FW		DROP
$FW		vpn0		ACCEPT

# The FOLLOWING POLICY MUST BE LAST
all		all		REJECT		info

/etc/shorewall/rules

#ACTION		SOURCE		DEST		PROTO	DPORT	SPORT	ORIGDEST	RATE	USER	MARK	CONNLIMIT	TIME	HEADERS	SWITCH	HELPER

?SECTION ALL
?SECTION ESTABLISHED
?SECTION RELATED
?SECTION INVALID
?SECTION UNTRACKED
?SECTION NEW

# Drop packets in the INVALID state
Invalid(DROP)  net	        $FW		tcp

# Drop Ping from the "bad" net zone.. and prevent your log from being flooded..
Ping(DROP)	net		$FW
Ping(ACCEPT)	loc		$FW

# Permit all ICMP traffic FROM the firewall TO the net zone
ACCEPT		$FW		net		icmp
ACCEPT		$FW		loc		icmp

#       Accept SSH connections from the internet for administration
#
SSH(DROP)       net		$FW		tcp	22
SSH(ACCEPT)     loc		$FW		tcp	22

ACCEPT          loc		$FW		tcp	8123
ACCEPT          loc		$FW		udp	161

# IPsec
#ACCEPT          net     $FW             ah
ACCEPT          net     $FW             esp
ACCEPT          net     $FW             udp     500
ACCEPT          net     $FW             udp     4500
#ACCEPT          $FW     net             ah
ACCEPT          $FW     net             esp
ACCEPT          $FW     net             udp     500
ACCEPT          $FW     net             udp     4500

# OpenVpn
ACCEPT          net     $FW     udp     1194
ACCEPT          $FW     net     udp     1194

/etc/shorewall/snat

#ACTION			SOURCE			DEST		PROTO	PORT	IPSEC	MARK	USER	SWITCH	ORIGDEST	PROBABILITY
MASQUERADE              192.168.1.0/24        ppp+

/etc/shorewall/start

##IPsec
iptables -I INPUT  -m policy --dir in --pol ipsec --proto esp -j ACCEPT
iptables -I FORWARD  -m policy --dir in --pol ipsec --proto esp -j ACCEPT
iptables -I FORWARD  -m policy --dir out --pol ipsec --proto esp -j ACCEPT
iptables -I OUTPUT   -m policy --dir out --pol ipsec --proto esp -j ACCEPT

# Accept from vpn to lan
iptables -t nat -I POSTROUTING -m policy --pol ipsec --dir out -j ACCEPT

## MTU/MSS fix
iptables -t mangle -A FORWARD -m policy --pol ipsec --dir in -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
iptables -t mangle -A FORWARD -m policy --pol ipsec --dir out -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360

#sip
WANIF=ppp0
LANIF=br0.111
iptables -I INPUT -m udp -p udp -i $WANIF --dport 5060 -j ACCEPT
iptables -I INPUT -m udp -p udp -i $WANIF --dport 7070:7080 -j ACCEPT
iptables -t mangle -A POSTROUTING -o $WANIF -p udp --dport 5060 -j CLASSIFY --set-class 2:1
iptables -t mangle -A POSTROUTING -o $WANIF -p udp --sport 7070:7080 -j CLASSIFY --set-class 2:1 
iptables -I INPUT -m udp -p udp -i $LANIF --dport 5060 -j ACCEPT
iptables -I INPUT -m udp -p udp -i $LANIF --dport 7070:7080 -j ACCEPT

/etc/shorewall/zones

###############################################################################
#ZONE		TYPE		OPTIONS		IN_OPTIONS	OUT_OPTIONS

fw		firewall
net		ipv4
loc		ipv4
tor		ipv4
dmz		ipv4
ipsec0		ipsec           mode=tunnel
vpn0		ipv4

Siproxdの設定

SIPフォンも旧ルーターに合わせて設定します。

/etc/siproxd.conf

if_inbound  = br0.111
if_outbound = ppp0
host_outbound = pikatyu.mydns.jp
hosts_allow_reg = 192.168.211.0/26
sip_listen_port = 5060
daemonize = 1
silence_log = 1
user = siproxd 
registration_file = /var/lib/siproxd/siproxd_registrations
autosave_registrations = 300
pid_file = /var/run/siproxd/siproxd.pid
rtp_proxy_enable = 1
rtp_port_low  = 7070
rtp_port_high = 7080
rtp_timeout = 300
default_expires = 600
tcp_timeout = 600
tcp_connect_timeout = 500
tcp_keepalive = 20
debug_level =      0x00000000
debug_port = 0
ua_string = Siproxd-UA
use_rport = 0
plugindir=/usr/lib/aarch64-linux-gnu/siproxd/

IKEv2(StrongSwan)とOpenVPNはとくに大きな変更はありません。OpenVPNサーバはsystemdで起動できるようにします。

systemd enable daemon nameとしてデーモンを登録してから設定をリロードします。

systemctl daemon-reload

その他

DHCPサーバを探す

ネットワークを弄っていると、いつのまにか旧設定が混在してあれ?ってことになることがあります。DHCPサーバをどこで設定したのか忘れるときがあります。その時の検索方法です。

sudo apt install dhcping
sudo dhcping -s 255.255.255.255

sysctlの最適化

ルータの落とし所はOpenWrtがよくわかっているので設定をそのままコピーしました。sshセッションがpppoeの再接続で切れるということがなくなります。

/etc/sysctl.d/10-default.conf

net.ipv4.conf.default.arp_ignore=1
net.ipv4.conf.all.arp_ignore=1
net.ipv4.ip_forward=1
net.ipv4.icmp_echo_ignore_broadcasts=1
net.ipv4.icmp_ignore_bogus_error_responses=1
net.ipv4.igmp_max_memberships=100
net.ipv4.tcp_fin_timeout=30
net.ipv4.tcp_keepalive_time=120
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_timestamps=1
net.ipv4.tcp_sack=1
net.ipv4.tcp_dsack=1
net.ipv6.conf.default.forwarding=1
net.ipv6.conf.all.forwarding=1

/etc/sysctl.d/11-nf-conntrack.conf

net.netfilter.nf_conntrack_acct=1
net.netfilter.nf_conntrack_checksum=0
net.netfilter.nf_conntrack_max=16384
net.netfilter.nf_conntrack_tcp_timeout_established=7440
net.netfilter.nf_conntrack_udp_timeout=60
net.netfilter.nf_conntrack_udp_timeout_stream=180