OpenWRT site2site IPsec (2)

# OpenWRT site2site IPsec (2)

[OpenWRT site2site IPsec (1)](http://qiita.com/t_umeno/items/4de97d1d005054cf7afd) からの続き

OpenWRT 15.05 R1(192.168.2.11)とOpenWRT 15.05 R2(192.168.2.12)の間で
192.168.101.0/24と192.168.102.0/24をIPsecトンネルで接続する。

![OpenWRT_network3.jpg](https://qiita-image-store.s3.amazonaws.com/0/102457/afbdf714-c507-fe16-4d5e-7c5e87fa7225.jpeg)


OpenWRT 15.05 R1,  OpenWRT 15.05 R2 いずれもstrongswan-fullをインストールする
なお、再起動のたびにパッケージのリストが失われるので、まずはopkg updateを実行すること。

```
# opkg update
# opkg install strongswan-full
```
# /etc/init.d/ipsec

[IPsec Basics]https://wiki.openwrt.org/doc/howto/vpn.ipsec.basics
から
\#/etc/init.d/ipsec
をコピペして実行すると下記の表示を出してエラーになる。

```
# /etc/init.d/ipsec start
kmod-crypto-aes missing
echo install with  "opkg install kmod-crypto-aes --nodeps"
```

```
# opkg install kmod-crypto-aes --nodeps
```
を実行してもkmod-crypt-aes がインストールされない。

[Changeset 46483]https://dev.openwrt.org/changeset/46483
によるとaesはモジュールではなく、kernel内部に統合されたので、
/etc/init.d/ipsec は下記修正することで動作するようになった。
※要はaesのモジュールのインストール有無を調べないようにした。

```
--- ipsec.old	2015-12-06 22:44:58.777630000 +0900
+++ ipsec	2015-12-06 22:43:32.149651000 +0900
@@ -194,7 +194,7 @@
     exit
   fi
  
-  for f in aes authenc cbc hmac md5 sha1; do
+  for f in authenc cbc hmac md5 sha1; do
     if [ `opkg list kmod-crypto-$f | wc -l` -eq 0 ]; then
       echo kmod-crypto-$f missing
       echo install with  \"opkg install kmod-crypto-$f --nodeps\"

```

編集後の /etc/init.d/ipsec

```
#!/bin/sh /etc/rc.common
#/etc/init.d/ipsec - version 5 - 2015/02/19
 
NAME=ipsec
START=60
STOP=60
 
. $IPKG_INSTROOT/lib/functions.sh
. $IPKG_INSTROOT/lib/functions/service.sh
 
FileSecrets=/var/ipsec/ipsec.secrets
FileConn=/var/ipsec/ipsec.conf
FileCommon=/var/ipsec/strongswan.conf
 
FolderCerts=/var/ipsec/ipsec.d
 
ConfigUser()
{
  local enabled
  local xauth
  local name
  local password
  local crt_subject
 
  config_get_bool enabled $1 enabled 0
  [[ "$enabled" == "0" ]] && return
 
  config_get_bool xauth       $1 xauth       0
  config_get      name        $1 name        ""
  config_get      password    $1 password    ""
 
  if [ $xauth -eq 1 -a "$name" != "" -a "$password" != "" ]; then
    echo "$name : XAUTH \"$password\"" >> $FileSecrets
  fi
}
 
 
ConfigPhase1() {
  local encryption_algorithm
  local hash_algorithm
  local dh_group
 
  config_get encryption_algorithm  "$1" encryption_algorithm
  config_get hash_algorithm        "$1" hash_algorithm
  config_get dh_group              "$1" dh_group
 
  Phase1Proposal=${Phase1Proposal}","${encryption_algorithm}-${hash_algorithm}-${dh_group}
}
 
ConfigTunnel() {
  local local_subnet
  local local_nat
  local remote_subnet
  local p2_proposal
  local pfs_group
  local encryption_algorithm
  local authentication_algorithm
 
  config_get local_subnet             "$1"           local_subnet
  config_get local_nat                "$1"           local_nat ""
  config_get remote_subnet            "$1"           remote_subnet
  config_get p2_proposal              "$1"           p2_proposal
  config_get pfs_group                "$p2_proposal" pfs_group
  config_get encryption_algorithm     "$p2_proposal" encryption_algorithm
  config_get authentication_algorithm "$p2_proposal" authentication_algorithm
 
  [[ "$local_nat" != "" ]] && local_subnet=$local_nat
 
  p2_proposal="${encryption_algorithm}-${authentication_algorithm}-${pfs_group}"
 
  echo "conn $ConfigName-$1" >> $FileConn
  echo "  keyexchange=ikev1" >> $FileConn
  echo "  left=$LocalGateway" >> $FileConn
  echo "  right=$RemoteGateway" >> $FileConn
  echo "  leftsubnet=$local_subnet" >> $FileConn
  if [ "$AuthenticationMethod" = "psk" ]; then
    echo "  leftauth=psk" >> $FileConn
    echo "  rightauth=psk" >> $FileConn
    echo "  rightsubnet=$remote_subnet" >> $FileConn
# should be auto=route when going to 5.0.1
    echo "  auto=start" >> $FileConn
  elif [ "$AuthenticationMethod" = "xauth_psk_server" ]; then
    echo "  authby=xauthpsk" >> $FileConn
    echo "  xauth=server" >> $FileConn
    echo "  modeconfig=pull" >> $FileConn
    echo "  rightsourceip=$remote_subnet" >> $FileConn
    echo "  auto=add" >> $FileConn
  fi
  if [ "$LocalIdentifier" != "" ]; then
    echo "  leftid=$LocalIdentifier" >> $FileConn
  fi
  if [ "$RemoteIdentifier" != "" ]; then
    echo "  rightid=$RemoteIdentifier" >> $FileConn
  fi
 
#  echo "  auth=esp" >> $FileConn
  echo "  esp=$p2_proposal" >> $FileConn
  echo "  ike=$Phase1Proposal" >> $FileConn
  echo "  type=tunnel" >> $FileConn
}
 
ConfigRemote() {
  local enabled
  local gateway
  local pre_shared_key
  local authentication_method
  local local_identifier
  local remote_identifier
 
  ConfigName=$1
 
  config_get_bool enabled "$1" enabled 0
  [[ "$enabled" == "0" ]] && return
 
  config_get gateway               "$1" gateway
  config_get pre_shared_key        "$1" pre_shared_key
  config_get authentication_method "$1" authentication_method
  config_get local_identifier      "$1" local_identifier
  config_get remote_identifier     "$1" remote_identifier
 
  AuthenticationMethod=$authentication_method
  LocalIdentifier=$local_identifier
  RemoteIdentifier=$remote_identifier
 
  RemoteGateway=$gateway
  if [ "$RemoteGateway" = "any" ]; then
    RemoteGateway="%any"
    LocalGateway=`ip route get 1.1.1.1 | awk -F"src" '/src/{gsub(/ /,"");print $2}'`
  else
    LocalGateway=`ip route get $RemoteGateway | awk -F"src" '/src/{gsub(/ /,"");print $2}'`
  fi
  echo "$LocalGateway $RemoteGateway : PSK \"$pre_shared_key\"" >> $FileSecrets
 
  Phase1Proposal=""
  config_list_foreach "$1" p1_proposal ConfigPhase1
  Phase1Proposal=`echo $Phase1Proposal | cut -b 2-`
 
  config_list_foreach "$1" tunnel ConfigTunnel
}
 
PrepareEnvironment() {
  local debug
 
  for d in cacerts aacerts ocspcerts crls acerts; do
    mkdir -p $FolderCerts/$d 2>/dev/null
  done
 
  if [ ! -L /etc/ipsec.d ]; then
    rm -rf /etc/ipsec.d 2>/dev/null
    ln -s $FolderCerts /etc/ipsec.d
  fi
 
  if [ ! -L /etc/ipsec.secrets ]; then
    rm /etc/ipsec.secrets 2>/dev/null
    ln -s $FileSecrets /etc/ipsec.secrets
  fi
 
  if [ ! -L /etc/strongswan.conf ]; then
    rm /etc/strongswan.conf 2>/dev/null
    ln -s $FileCommon /etc/strongswan.conf
  fi
 
  if [ ! -L /etc/ipsec.conf ]; then
    rm /etc/ipsec.conf 2>/dev/null
    ln -s $FileConn /etc/ipsec.conf
  fi
 
  echo "# generated by /etc/init.d/ipsec" > $FileConn
  echo "version 2" > $FileConn
  echo "# generated by /etc/init.d/ipsec" > $FileSecrets
 
  config_get debug "$1" debug 0
 
  echo "# generated by /etc/init.d/ipsec" > $FileCommon
  echo "charon {" >> $FileCommon
  echo "  load = aes des sha1 sha2 md5 gmp random nonce hmac stroke kernel-netlink socket-default updown" >> $FileCommon
  echo "  filelog {" >> $FileCommon
  echo "    /var/log/charon.log {" >> $FileCommon
  echo "      time_format = %b %e %T" >> $FileCommon
  echo "      ike_name = yes" >> $FileCommon
  echo "      append = no" >> $FileCommon
  echo "      default = " $debug >> $FileCommon
  echo "      flush_line = yes" >> $FileCommon
  echo "    }" >> $FileCommon
  echo "  }" >> $FileCommon
  echo "}" >> $FileCommon
 
}
 
CheckInstallation() {
  if [ ! -x /usr/sbin/ip ]; then
    echo /usr/sbin/ip missing
    echo install with \"opkg install ip\"
    exit
  fi
 
  for f in authenc cbc hmac md5 sha1; do
    if [ `opkg list kmod-crypto-$f | wc -l` -eq 0 ]; then
      echo kmod-crypto-$f missing
      echo install with  \"opkg install kmod-crypto-$f --nodeps\"
      exit
    fi
  done
 
  for f in aes gmp hmac kernel-netlink md5 random sha1 updown attr resolve; do
    if [ ! -f /usr/lib/ipsec/plugins/libstrongswan-${f}.so ]; then
      echo /usr/lib/ipsec/plugins/$f missing
      echo install with \"opkg install strongswan-mod-$f --nodeps\"
      exit
    fi
  done
}
 
start() {
  CheckInstallation
 
  config_load ipsec
  config_foreach PrepareEnvironment ipsec
  config_foreach ConfigRemote remote
 
  config_load users
  config_foreach ConfigUser user
 
  /usr/sbin/ipsec start
}
 
stop() {
  /usr/sbin/ipsec stop
}
```

この/etc/init.d/ipsec を OpenWRT 15.05 R1 と OpenWRT 15.05 R2 で使用する

#/etc/config/ipsec

[Strongswan IPsec Configuration]https://wiki.openwrt.org/doc/uci/ipsec
の
Example 1 taken from the IPSec site to site howto. には、

```
config 'ipsec'
  option 'zone' 'vpn'

config 'remote' 'acme'
  option 'enabled' '1'
  option 'gateway' '7.7.7.7'
  option 'authentication_method' 'psk'
  option 'pre_shared_key' 'yourpasswordhere'
  list   'p1_proposal' 'pre_g2_aes_sha1'
  list   'sainfo' 'acme_dmz'
  list   'sainfo' 'acme_lan'

config 'p1_proposal' 'pre_g2_aes_sha1'
  option 'encryption_algorithm' 'aes128'
  option 'hash_algorithm' 'sha1'
  option 'dh_group' 'modp1024'

config 'tunnel' 'acme_lan'
  option 'local_subnet' '192.168.2.64/26'
  option 'remote_subnet' '10.1.2.0/24'
  option 'p2_proposal' 'g2_aes_sha1'

config 'p2_proposal' 'g2_aes_sha1'
  option 'pfs_group' 'modp1024'
  option 'encryption_algorithm' 'aes 128'
  option 'authentication_algorithm' 'sha1'

```

の記載があるが、

```
  list   'sainfo' 'acme_dmz'
  list   'sainfo' 'acme_lan'
```

の記載は誤り

```
  list   'tunnel' 'acme_dmz'
  list   'tunnel' 'acme_lan'
```
の様に'sainfo'ではなく'tunnel'を記載すること。

OpenWRT 15.05 R1 設定変更後の /etc/config/ipsec

```
config 'ipsec'
  option 'zone' 'vpn'

config 'remote' 'r2'
  option 'enabled' '1'
  option 'gateway' '192.168.2.12'
  option 'authentication_method' 'psk'
  option 'pre_shared_key' 'yourpasswordhere'
  list   'p1_proposal' 'pre_g2_aes_sha1'
  list   'tunnel' 'r2_lan'

config 'p1_proposal' 'pre_g2_aes_sha1'
  option 'encryption_algorithm' 'aes128'
  option 'hash_algorithm' 'sha1'
  option 'dh_group' 'modp1024'

config 'tunnel' 'r2_lan'
  option 'local_subnet' '192.168.101.0/24'
  option 'remote_subnet' '192.168.102.0/24'
  option 'p2_proposal' 'g2_aes_sha1'

config 'p2_proposal' 'g2_aes_sha1'
  option 'pfs_group' 'modp1024'
  option 'encryption_algorithm' 'aes 128'
  option 'authentication_algorithm' 'sha1'
```

OpenWRT 15.05 R2 設定変更後の /etc/config/ipsec

```
config 'ipsec'
  option 'zone' 'vpn'

config 'remote' 'r1'
  option 'enabled' '1'
  option 'gateway' '192.168.2.11'
  option 'authentication_method' 'psk'
  option 'pre_shared_key' 'yourpasswordhere'
  list   'p1_proposal' 'pre_g2_aes_sha1'
  list   'tunnel' 'r1_lan'

config 'p1_proposal' 'pre_g2_aes_sha1'
  option 'encryption_algorithm' 'aes128'
  option 'hash_algorithm' 'sha1'
  option 'dh_group' 'modp1024'

config 'tunnel' 'r1_lan'
  option 'local_subnet' '192.168.102.0/24'
  option 'remote_subnet' '192.168.101.0/24'
  option 'p2_proposal' 'g2_aes_sha1'

config 'p2_proposal' 'g2_aes_sha1'
  option 'pfs_group' 'modp1024'
  option 'encryption_algorithm' 'aes 128'
  option 'authentication_algorithm' 'sha1'
```

#IPsec の状態確認

OpenWRT 15.05 R1 や OpenWRT 15.05 R2 で ipsec status や ipsec statusall を実行する事で動作確認できる。
192.168.101.0/24 と 192.168.102.0/24 間で正常にIPsecのトンネルが作成されている状態で
OpenWRT 15.05 R1 で ipsec status や ipsec statusall の実行結果を下記に示す。

```
root@OpenWrt:~# ipsec status
Security Associations (1 up, 0 connecting):
   r2-r2_lan[21]: ESTABLISHED 2 hours ago, 192.168.2.11[192.168.2.11]...192.168.2.12[192.168.2.12]
   r2-r2_lan{72}:  INSTALLED, TUNNEL, reqid 1, ESP SPIs: c5b15128_i c18bf6e2_o
   r2-r2_lan{72}:   192.168.101.0/24 === 192.168.102.0/24 
root@OpenWrt:~# ipsec statusall
Status of IKE charon daemon (strongSwan 5.3.3, Linux 3.18.20, i686):
  uptime: 2 days, since Dec 13 11:09:32 2015
  malloc: sbrk 102400, mmap 0, used 88688, free 13712
  worker threads: 11 of 16 idle, 5/0/0/0 working, job queue: 0/0/0/0, scheduled: 2
  loaded plugins: charon aes des sha1 sha2 md5 gmp random nonce hmac stroke kernel-netlink socket-default updown
Listening IP addresses:
  192.168.2.11
  192.168.101.1
Connections:
   r2-r2_lan:  192.168.2.11...192.168.2.12  IKEv1
   r2-r2_lan:   local:  [192.168.2.11] uses pre-shared key authentication
   r2-r2_lan:   remote: [192.168.2.12] uses pre-shared key authentication
   r2-r2_lan:   child:  192.168.101.0/24 === 192.168.102.0/24 TUNNEL
Security Associations (1 up, 0 connecting):
   r2-r2_lan[21]: ESTABLISHED 2 hours ago, 192.168.2.11[192.168.2.11]...192.168.2.12[192.168.2.12]
   r2-r2_lan[21]: IKEv1 SPIs: a3604b19de23fefa_i f893a59906be6ba0_r*, pre-shared key reauthentication in 39 minutes
   r2-r2_lan[21]: IKE proposal: AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024
   r2-r2_lan{72}:  INSTALLED, TUNNEL, reqid 1, ESP SPIs: c5b15128_i c18bf6e2_o
   r2-r2_lan{72}:  AES_CBC_128/HMAC_SHA1_96, 0 bytes_i, 0 bytes_o, rekeying in 18 minutes
   r2-r2_lan{72}:   192.168.101.0/24 === 192.168.102.0/24 
root@OpenWrt:~# 

```
また、PC1(192.168.101.102/24) から PC2 (192.168.102.247/24)にpingが到達し、かつ、192.168.2.0のセグメントでICMPパケットが見当たらない事を確認する事でIPsecトンネルが正常に動作している事を確認できる。

#補足 
##luci (web設定)
OpenWRTのweb serverに接続した際にブラウザに下記が表示される事がある

```
/usr/lib/lua/luci/dispatcher.lua:255: No valid theme found
stack traceback:
	[C]: in function 'assert'
	/usr/lib/lua/luci/dispatcher.lua:255: in function 'dispatch'
	/usr/lib/lua/luci/dispatcher.lua:168: in function </usr/lib/lua/luci/dispatcher.lua:167>
```

[ #16775 closed defect (fixed) ]https://dev.openwrt.org/ticket/16775
に従って

```
# opkg remove luci
# opkg remove luci-theme-bootstrap
# opkg install luci
```

を実行したら正常にWebブラウザ表示されるようになった。