User Tools

Site Tools


doc:howto:vpn.ipsec.basics

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
doc:howto:vpn.ipsec.basics [2012/12/21 16:03]
miceliux Add hotplug.d script
doc:howto:vpn.ipsec.basics [2015/02/19 12:16] (current)
birnenschnitzel [Page summary]
Line 1: Line 1:
 ====== IPsec Basics ====== ====== IPsec Basics ======
 +| For an overview over all existing Virtual private network (VPN)-related articles in the OpenWrt wiki, please visit [[doc/​howto/​vpn.overview]] |
  
-A quick starters quide based on Backfire 10.03.1-rc6. Maybe it will save you and me time if one has to setup an IPsec VPN in the future. Hopefully it will ecourage other people to use Openwrt as an IPsec VPN router. We cannot provide a graphical user interface at the moment but at least it is a solid alternative to commercial IPsec appliances. If you came here for informations about [[http://​www.openswan.org|Openswan]] on OpenWrt you may be disappointed. This guide is only about racoon.+A quick starters quide based on OpenWrt Barrier Breaker 14.07. Maybe it will save you and me time if one has to setup an IPsec VPN in the future. Hopefully it will ecourage other people to use Openwrt as an IPsec VPN router. We cannot provide a graphical user interface at the moment but at least it is a solid alternative to commercial IPsec appliances. ​
  
---UPDATE-- Openswan documentation is being put together here [[doc:​howto:​vpn.ipsec.site2site.openswan|IPsec Site To Site Using Openswan]] 
  
 ===== Packages ===== ===== Packages =====
  
-If not already installed on your router you need the at least those packages+If not already installed on your router you need the at least those packages
  
-  * ipsec-toolsracoon, setkey, and kernel encryption modules +  * strongswan-defaulteverything needed ​for IPsec tunnels ​
-  * kmod-crypto-authenc:​ Module ​for block cipher modes (AEAD) (automatically installed with ipsec-tools in latest trunk) +
-  * kmod-ipsec: Basic security module (automatically installed with ipsec-tools in latest trunk) +
-  * kmod-ipsec4:​ IPv4 security module+
   * ip: Required to make scripting easier   * ip: Required to make scripting easier
-  * openssl-util:​ Certificate handling 
   * iptables-mod-nat-extra:​ For VPN networks with [[vpn.ipsec.overlappingsubnets|overlapping IP addresses]]   * iptables-mod-nat-extra:​ For VPN networks with [[vpn.ipsec.overlappingsubnets|overlapping IP addresses]]
-  * djbdns-utils: for simpler name resolving than old "nslookup ​| awk" thing (may also be named djbdns-tools)+  * djbdns-tools: for simpler name resolving than nslookup
  
-Altogehter those packages will eat up about 1,2 MB of your router'​s flash memory. The racoon and ip binaries will already be 650KB. Maybe it is time for an [[extroot]] installation?​+Altogehter those packages will eat up about some MB of your router'​s flash memory. Maybe it is time for an [[extroot]] installation?​
  
  
Line 24: Line 20:
 ===== Configuration concept ===== ===== Configuration concept =====
  
-With Linux default IPsec daemon is called racoon. For this one normally edits some files+If you already worked with strongSwan you should know the different ​files you need to configure. They include
  
-  * **/etc/racoon.conf**: Central configuration file & endpoint definitions +  * **/etc/strongswan.conf**: Central configuration file  
-  * **/etc/racoon/psk.txt**: List of preshared keys +  * **/etc/ipsec.conf**:​ Tunnel definitions 
-  * **/etc/racoon/​setkey.conf**: Security policies ​for tunnels+  * **/etc/ipsec.secrets**: List of preshared keys 
 +  * **/etc/ipsec.d**: Folder ​for certificates
  
-The major challenges are handling setkey.conf ​with dynamic IP addresses and clean integration into the OpenWrt configuration concept. To solve this we will use a hierarchical configuration processThat involves+:!: Remark! If you you want to stay with that configuration you have reached ​the wrong place
  
-  ​* **/​etc/​config/​racoon**: The OpenWrt configuration file for racoon +The major challenge is handling all of those files automatically with a clean integration into the OpenWrt configuration concept. To solve this we will use a hierarchical configuration process. That involves 
-  * **/​etc/​init.d/​racoon**: The racoon ​start script. It will generate the required configuration files for racoon + 
-  * **/var/racoon/​racoon.conf**: The generated ​racoon ​config +  ​* **/​etc/​config/​ipsec**: The OpenWrt configuration file for strongSwan 
-  * **/var/racoon/psk.txt** : The generated file with preshared keys +  * **/​etc/​init.d/​ipsec**: The Strongswan ​start script. It will generate the required configuration files for strongSwan 
-  * **/var/racoon/cert**: The folder with generated ​certificates+  * **/var/ipsec.conf**: The generated ​Strongswan ​config 
 +  * **/var/ipsec.secrets** : The generated file with preshared keys 
 +  * **/var/strongswan.conf** : The generated ​central configuration file
    
 Here a short example of the configuration methodology when having two VPN tunnels to ACME and Yabadoo networks ​ Here a short example of the configuration methodology when having two VPN tunnels to ACME and Yabadoo networks ​
  
 <​code>​ <​code>​
-#/​etc/​config/​racoon +#/​etc/​config/​ipsec 
-config 'tunnel' '​ACME'​+config 'remote' '​ACME'​
   option '​enabled'​ '​1'​   option '​enabled'​ '​1'​
-  option 'remote' '​1.2.3.4'​ +  option 'gateway' '​1.2.3.4'​ 
-  list   '​sainfo' '​acme_lan'​+  list   '​tunnel' '​acme_lan'​
   ...   ...
  
-config 'sainfo' '​acme_lan'​ +config 'tunnel' '​acme_lan'​ 
-  option 'local_address' '​192.168.213.64/​26'​ +  option 'local_subnet' '​192.168.213.64/​26'​ 
-  option 'remote_address' '​192.168.10.0/​24'​+  option 'remote_subnet' '​192.168.10.0/​24'​
   ...   ...
  
-config 'tunnel' '​Yabadoo'​+config 'remote' '​Yabadoo'​
   option '​enabled'​ '​1'​   option '​enabled'​ '​1'​
-  option 'remote' '​5.6.7.8'​+  option 'gateway' '​5.6.7.8'​
 </​code>​ </​code>​
  
-Read more about the complete syntax for [[doc:uci:racoon|/​etc/​config/​racoon]].+Read more about the complete syntax for [[doc:uci:ipsec|/​etc/​config/​ipsec]].
  
  
 ===== IKE Daemon ===== ===== IKE Daemon =====
  
-As already mentioned it can be little scary to insert security polices into the kernelEspecially when you have a reconnecting interface with a dynamic outside IP. But to be honest all we have to know is already inside our /etc/config/racoon fileSo we just have to use the startup ​script to parse those files and hand them over to the IPSec stack via setkey commandOur solution involves+To let Charon run as a background daemon we can place hook in the init environmentTherefore create the file **/etc/init.d/ipsec** and set the executable bitRemark: This script ​is in an early alpha state. It currently works for site to site tunnels with preshared keys. Feel free to enhance it.
  
-  * automatically determine interfaces and IPs +<code bash> 
-  * allow multiple sainfo sets per tunnel +#!/bin/sh 
-  * if racoon is already running reload policies only +#/​etc/​init.d/​ipsec - version 5 - 2015/02/19
-  * generate certificates and their hashes+
  
-To let racoon run as a background daemon we can place a hook in the init environment. Therefore create the file **/​etc/​init.d/​racoon** and set the executable bit. Remark: This script is in an advanced beta state. It currently works for site to site or roadwarrior tunnels with either preshared keys or RSA certificates. Feel free to enhance it.+NAME=ipsec 
 +START=60 
 +STOP=60
  
-Enhancement: ​ It works also with cisco ASA remote endpoint now :-) +. $IPKG_INSTROOT/​lib/​functions.sh 
 +. $IPKG_INSTROOT/​lib/​functions/​service.sh
  
-<code bash> +FileSecrets=/var/ipsec/ipsec.secrets 
-#!/bin/sh /​etc/​rc.common +FileConn=/var/ipsec/ipsec.conf 
-#/​etc/​init.d/​racoon - version 26 +FileCommon=/var/ipsec/strongswan.conf 
-  + 
-NAME=racoon +FolderCerts=/var/ipsec/ipsec.d 
-PROG=/usr/sbin/racoon + 
-START=60 +ConfigUser()
-STOP=60 +
-  +
-/​etc/​functions.sh +
-  +
-ConfigFile="/var/racoon/racoon.conf" +
-PSKFile="/var/racoon/psk.txt" +
-UserFile="/var/racoon/xauthuser.txt" +
-CertificatePath="/​var/​racoon/​cert"​ +
-CallParameters=""​ +
-RoadWarriorRemote="​anonymous"​ +
-RoadWarriorDNS=""​ +
-RoadWarriorDomain=""​ +
-RoadWarriorCerts=""​ +
-MainConfigDone=0 +
-  +
-UserConfig()+
 { {
   local enabled   local enabled
Line 103: Line 88:
   local password   local password
   local crt_subject   local crt_subject
- +
   config_get_bool enabled $1 enabled 0   config_get_bool enabled $1 enabled 0
   [[ "​$enabled"​ == "​0"​ ]] && return   [[ "​$enabled"​ == "​0"​ ]] && return
- +
   config_get_bool xauth       $1 xauth       0   config_get_bool xauth       $1 xauth       0
   config_get ​     name        $1 name        ""​   config_get ​     name        $1 name        ""​
   config_get ​     password ​   $1 password ​   ""​   config_get ​     password ​   $1 password ​   ""​
-  config_get ​     crt_subject $1 crt_subject ""​ +
- +
   if [ $xauth -eq 1 -a "​$name"​ != ""​ -a "​$password"​ != ""​ ]; then   if [ $xauth -eq 1 -a "​$name"​ != ""​ -a "​$password"​ != ""​ ]; then
-    echo "$name $password"​ >> $UserFile +    echo "​$name ​: XAUTH \"$password\"" >> $FileSecrets
-  fi +
-  +
-  if [ "​$crt_subject"​ != ""​ ]; then +
-    RoadWarriorCerts="​${RoadWarriorCerts}peers_identifier asn1dn \"​$crt_subject\";"​+
   fi   fi
 } }
-  + 
-CreateSA() { + 
-  local LocalEndpoint=`ip route get $3 | awk -F"​src"​ '/​src/​{gsub(/​ /,""​);​print $2}'​` +ConfigPhase1() {
-  +
-  echo "​spdadd $1 $2 any -P out ipsec \ +
-        esp/​tunnel/​$LocalEndpoint-$3/​unique;​ \ +
-        spdadd $2 $1 any -P in ipsec \ +
-        esp/​tunnel/​$3-$LocalEndpoint/​unique;​ \ +
-       "​ | setkey -c 1>&​2 +
-+
-  +
-RoadWarriorSubnet() { +
-  local i +
-  +
-  let "​i=255<<​(24-${1#​*/​}+8)&​255"​ +
-  echo " ​ netmask4 255.255.255.$i;"​ +
-  +
-  i="​${1%/​*}"​ +
-  let "​i=${i##​*.}+1"​ +
-  echo " ​ network4 ${1%.*}.$i;"​ +
-+
-  +
-MainConfig() { +
-  local foreground +
-  local debug +
-  local listen +
-  +
-  config_get_bool foreground ​       $1 foreground 0 +
-  config_get_bool debug             $1 debug      0 +
-  config_get ​     listen ​           $1 listen ​    ""​ +
-  config_get ​     RoadWarriorDNS ​   $1 dns        ""​ +
-  config_get ​     RoadWarriorDomain $1 domain ​    ""​ +
-  +
-  [[ $foreground -ne 0 ]] && CallParameters="​-F"​ +
-  [[ $debug -ne 0 ]]      && CallParameters=$CallParameters"​ -d" +
-  +
-  echo "# auto generated by /​etc/​init.d/​racoon"​ +
-  echo "path pre_shared_key \"​$PSKFile\";"​ +
-  echo "path certificate \"​$CertificatePath\";"​ +
-  echo "​padding {" +
-  echo " ​ maximum_length 20; randomize off;"​ +
-  echo " ​ strict_check off; exclusive_tail off;"​ +
-  echo "​}"​ +
-  echo "timer {" +
-  echo " ​ counter 5; interval 20 sec; persend 1;" +
-  echo " ​ phase1 30 sec; phase2 15 sec;"​ +
-  echo "​}"​ +
-  echo ""​ +
-  +
-  if [ "​$listen"​ != ""​ ]; then +
-    echo "​listen {" +
-    config_list_foreach "​$1"​ listen AddListenIP +
-    echo "​}"​ +
-    echo ""​ +
-  fi +
-  MainConfigDone=1 +
-+
-  +
-AddListenIP() { +
-  local value="​$1"​ +
-  . /​lib/​functions/​network.sh +
-  local retvalue +
-  network_get_ipaddr listenIP "​$value"​ +
-  if [ $? -eq 0 ]; then +
-    if [ "​$listenIP"​ != ""​ ]; then +
-      echo " ​ isakmp $listenIP;"​ +
-      echo " ​ isakmp_natt $listenIP [4500];"​ +
-    fi +
-  fi +
-  network_get_ipaddr6 listenIP "​$value"​ +
-  if [ $? -eq 0 ]; then +
-    if [ "​$listenIP"​ != ""​ ]; then +
-      echo " ​ isakmp $listenIP;"​ +
-      echo " ​ isakmp_natt $listenIP [4500];"​ +
-    fi +
-  fi +
-+
-  +
-TunnelConfig() { +
-  local enabled +
-  local remote +
-  local remote_device +
-  local preshared_key +
-  local exchange_mode +
-  local my_identifier +
-  local my_identifier_type +
-  local certificate +
-  local remote_device +
-  +
-  config_get_bool enabled "​$1"​ enabled 0 +
-  [[ "​$enabled"​ == "​0"​ ]] && return +
-  +
-  config_get remote ​            "​$1"​ remote +
-  config_get remote_device ​     "​$1"​ remote_device ""​ +
-  config_get pre_shared_key ​    "​$1"​ pre_shared_key ""​ +
-  config_get exchange_mode ​     "​$1"​ exchange_mode +
-  config_get my_identifier ​     "​$1"​ my_identifier ""​ +
-  config_get my_identifier_type "​$1"​ my_identifier_type "​fqdn"​ +
-  config_get certificate ​       "​$1"​ certificate ""​ +
-  config_get dpd_delay "​$1"​ dpd_delay ""​ +
-  +
-  if [ "​$remote"​ != "​$RoadWarriorRemote"​ ]; then +
-    if [ -x /​usr/​bin/​dnsip ] ; then +
-      remote=`/​usr/​bin/​dnsip $remote` +
-    else  +
-      remote=`nslookup "​$remote"​ | awk 'NR==5 { print $3 }'` +
-    fi +
-    prg=`racoon -V 2>/​dev/​null| grep "​ipsec-tools 0.8" | wc -l` +
-    if [ $prg -eq 0 ]; then +
-      echo "​remote $remote {" +
-    else +
-      echo "​remote \"​$1\"​ {" +
-      echo " ​ remote_address $remote;"​ +
-    fi +
-  +
-  else +
-    echo "​remote anonymous {" +
-    echo " ​ generate_policy on;" +
-  fi +
-  +
-  if [ "​$pre_shared_key"​ != ""​ ]; then +
-    if [ "​$remote"​ != "​$RoadWarriorRemote"​ ]; then +
-      echo "​$remote $pre_shared_key"​ >> $PSKFile +
-    else +
-      echo "* $pre_shared_key"​ >> $PSKFile +
-    fi +
-    if [ "​$my_identifier"​ != ""​ -a "​$my_identifier_type"​ != ""​ ]; then +
-      echo " ​ my_identifier $my_identifier_type ​ \"​$my_identifier\";"​ +
-    fi +
-  elif [ "​$certificate"​ != ""​ ]; then +
-    echo " ​ verify_cert on;" +
-    echo " ​ certificate_type x509 \"​$certificate.crt\"​ \"​$certificate.key\";"​ +
-    echo " ​ my_identifier asn1dn;"​ +
-    if [ "​$remote"​ == "​$RoadWarriorRemote"​ ]; then +
-      echo " ​ verify_identifier on;" +
-      echo " ​ "​$RoadWarriorCerts +
-    else +
-      echo " ​ peers_identifier asn1dn;"​ +
-    fi +
-  fi +
-  +
-  echo " ​ exchange_mode $exchange_mode;"​ +
-  echo " ​ proposal_check obey;"​ +
-  echo " ​ nat_traversal on;" +
-  if [ "​$dpd_delay"​ != ""​ ]; then +
-    echo " ​ dpd_delay $dpd_delay;"​ +
-  fi +
-  +
-  config_list_foreach "​$1"​ p1_proposal ConfigP1 +
-  echo "​}"​ +
-  +
-  AnonSA=0 +
-  config_list_foreach "​$1"​ sainfo ConfigSA $tunnel $remote +
-  [[ "​$remote"​ == "​$RoadWarriorRemote"​ ]] && echo "​}"​ +
-+
-  +
-ConfigP1() { +
-  local lifetime+
   local encryption_algorithm   local encryption_algorithm
   local hash_algorithm   local hash_algorithm
-  local authentication 
   local dh_group   local dh_group
-  +
-  config_get lifetime ​             "​$1"​ lifetime 28800+
   config_get encryption_algorithm ​ "​$1"​ encryption_algorithm   config_get encryption_algorithm ​ "​$1"​ encryption_algorithm
   config_get hash_algorithm ​       "​$1"​ hash_algorithm   config_get hash_algorithm ​       "​$1"​ hash_algorithm
-  config_get authentication_method "​$1"​ authentication_method 
   config_get dh_group ​             "​$1"​ dh_group   config_get dh_group ​             "​$1"​ dh_group
-  + 
-  ​echo " ​ proposal ​{" +  ​Phase1Proposal=${Phase1Proposal}","${encryption_algorithm}-${hash_algorithm}-${dh_group}
-  echo " ​   ​lifetime time $lifetime sec;"​ +
-  echo " ​   ​encryption_algorithm $encryption_algorithm;"​ +
-  echo " ​   ​hash_algorithm $hash_algorithm;"​ +
-  echo " ​   authentication_method $authentication_method;"​ +
-  echo " ​   ​dh_group ​$dh_group;"​ +
-  echo "  ​}"+
 } }
-  + 
-ConfigSA() { +ConfigTunnel() {
-  local tunnel=`echo $2 | cut -d" " -f1` +
-  local sainfo=$1 +
-  local remote=`echo $2 | cut -d" " -f2`+
   local local_subnet   local local_subnet
   local local_nat   local local_nat
Line 307: Line 120:
   local p2_proposal   local p2_proposal
   local pfs_group   local pfs_group
-  local lifetime 
   local encryption_algorithm   local encryption_algorithm
-  ​local local authentication_algorithm +  local authentication_algorithm 
-  + 
-  config_get local_subnet ​            "​$sainfo" ​     local_subnet +  config_get local_subnet ​            "​$1" ​          ​local_subnet 
-  config_get local_nat ​               "$sainfo" ​     local_nat ""​ +  config_get local_nat ​               "$1" ​          ​local_nat ""​ 
-  config_get remote_subnet ​           "$sainfo" ​     remote_subnet +  config_get remote_subnet ​           "$1" ​          ​remote_subnet 
-  config_get p2_proposal ​             "$sainfo" ​     p2_proposal+  config_get p2_proposal ​             "$1" ​          ​p2_proposal
   config_get pfs_group ​               "​$p2_proposal"​ pfs_group   config_get pfs_group ​               "​$p2_proposal"​ pfs_group
-  config_get lifetime ​                "​$p2_proposal"​ lifetime 3600 
   config_get encryption_algorithm ​    "​$p2_proposal"​ encryption_algorithm   config_get encryption_algorithm ​    "​$p2_proposal"​ encryption_algorithm
   config_get authentication_algorithm "​$p2_proposal"​ authentication_algorithm   config_get authentication_algorithm "​$p2_proposal"​ authentication_algorithm
- +
   [[ "​$local_nat"​ != ""​ ]] && local_subnet=$local_nat   [[ "​$local_nat"​ != ""​ ]] && local_subnet=$local_nat
-  + 
-  if [ "$remote" = "$RoadWarriorRemote" ]; then +  p2_proposal="​${encryption_algorithm}-${authentication_algorithm}-${pfs_group}"​ 
-    ​let AnonSA=$AnonSA+1+ 
 +  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   fi
-  [$AnonSA -eq 1 ]] && echo "sainfo anonymous {" +  ​if "$LocalIdentifier"​ != ""​ ]; then 
-  if [ $AnonSA -eq 0 ]; then +    echo " ​ ​leftid=$LocalIdentifier" ​>> $FileConn
-    CreateSA $local_subnet $remote_subnet $remote +
-    echo "sainfo address ​$local_subnet any address $remote_subnet any {"+
   fi   fi
-  if [ $AnonSA -lt 2 ]; then +  if [ "$RemoteIdentifier" != ""​ ]; then 
-    [[ "$remote_device" != "asa" ​]] && ​ echo " ​ pfs_group $pfs_group;"​ +    echo "  ​rightid=$RemoteIdentifier" ​>> ​$FileConn
-    echo " ​ lifetime time $lifetime sec;"​ +
-    echo " ​ encryption_algorithm $encryption_algorithm;"​ +
-    echo " ​ authentication_algorithm $authentication_algorithm;"​ +
-    echo " ​ compression_algorithm deflate;"​ +
-    echo "​}"​ +
-  fi +
-  if [ $AnonSA -eq 1 ]; then +
-    echo "​mode_cfg {" +
-    echo "  ​auth_source system;"​ +
-    echo " ​ conf_source local;"​ +
-    [[ "​$RoadWarriorDNS" ​   !""​ ]] && echo " ​ dns4 $RoadWarriorDNS;"​ +
-    [[ "$RoadWarriorDomain"​ != ""​ ]] && echo " ​ default_domain \"​$RoadWarriorDomain\";"​ +
-    RoadWarriorSubnet $remote_subnet +
-  fi +
-  if [ $AnonSA -gt 0 ]; then +
-    echo " ​ split_network include $local_subnet;"​+
   fi   fi
 +
 +#  echo " ​ auth=esp"​ >> $FileConn
 +  echo " ​ esp=$p2_proposal"​ >> $FileConn
 +  echo " ​ ike=$Phase1Proposal"​ >> $FileConn
 +  echo " ​ type=tunnel"​ >> $FileConn
 } }
-  
-CertConfig() { 
-  local val 
-  local hash 
-  
-  for opt in key crt; do 
-    config_get val "​$1"​ "​$opt"​ ""​ 
-    if [ "​$val"​ != ""​ ]; then 
-      echo $val | sed "​s/​-\+[A-Z ]\+-\+/​\n&​\n/​g"​ \ 
-                | sed "​s/​.\{50,​50\}/&​\n/​g"​ \ 
-                | sed "/​^$/​d"​ > $CertificatePath/​$1.$opt 
-      chmod 600 $CertificatePath/​$1.$opt 
-    fi 
-  done 
-  
-  hash=`openssl x509 -noout -hash -in $CertificatePath/​$1.crt` 
-  ln -s -f $CertificatePath/​$1.crt $CertificatePath/​$hash.0 
-} 
-  
-CheckEnvironment() { 
-  local prg 
-  for prg in /​usr/​bin/​openssl /​usr/​sbin/​ip;​ do 
-    if [ ! -x $prg ]; then 
-      echo "​Error! $prg missing. Exit now." 
-      exit 
-    fi 
-  done 
-  
-  mkdir -m 0700 -p /var/racoon 
-  mkdir -m 0700 -p $CertificatePath 
-} 
-  
-start() { 
-  local active=`ps | grep /​usr/​sbin/​racoon | grep -v grep | wc -l` 
-  
-  CheckEnvironment 
-  
-  if [ $active -eq 0 -o "​$1"​ = "​force"​ ]; then 
-    rm $UserFile 2>/​dev/​null 
-    config_load users 
-    config_foreach UserConfig user 
-  fi 
-  
-  config_load racoon 
-  
-  if [ $active -ne 0 -a "​$1"​ != "​force"​ ]; then 
-    PSKFile=/​dev/​null 
-    ConfigFile=/​dev/​null 
-  else 
-    config_foreach CertConfig certificate 
-    echo "# auto generated by /​etc/​init.d/​racoon"​ > $PSKFile 
-    chmod 600 $PSKFile 
-  fi 
-  
-  config_foreach MainConfig racoon > $ConfigFile 
-  if [ $MainConfigDone -eq 0 ]; then 
-    MainConfig XXX > $ConfigFile 
-  fi 
-  
-  echo "​flush;​ spdflush;"​ | setkey -c 
-  config_foreach TunnelConfig tunnel >> $ConfigFile 
-  
-  if [ $active -eq 0 ]; then 
-    /​usr/​sbin/​racoon $CallParameters -f $ConfigFile 
-  elif [ "​$1"​ = "​force"​ ]; then 
-    racoonctl reload-config 
-  fi 
-} 
-  
-stop() { 
-  pid=`ps | grep /​usr/​sbin/​racoon | grep -v grep | awk '{ print $1}'` 
-  [[ "​$pid"​ != ""​ ]] && kill $pid 
-  echo "​flush;​ spdflush;"​ | setkey -c 
-} 
-  
-restart() { 
-  start force 
-} 
-</​code>​ 
  
-Before you start racoon with the web interface you should make a dry run from command line. Enable forground operation in /​etc/​config/​racoon by setting **option '​foreground'​ '​1'​** in section racoon and call **/​etc/​init.d/​racoon start**. This will show you if there are any errors in your generated configuration file **/​var/​racoon/​racoon.conf**. Afterwards you can control startup behaviour with LuCI.+ConfigRemote() { 
 +  local enabled 
 +  local gateway 
 +  local pre_shared_key 
 +  local authentication_method 
 +  local local_identifier 
 +  local remote_identifier
  
-{{:​doc:​howto:​ipsec_racoon.png|}}+  ConfigName=$1
  
-An automatic reload of security policies after a router reconnect is very helpful. Luckily pppd will call all scripts in /​etc/​ppp/​ip-up.d after pppoe-wan is up again. Create a small script in this directory that calls the racoon init script. If it detects that racoon is running already it will only set the security policies.+  config_get_bool enabled "​$1"​ enabled 0 
 +  [[ "​$enabled"​ == "​0"​ ]] && return
  
-<code bash> +  config_get gateway ​              "​$1"​ gateway 
-#!/bin/sh +  ​config_get pre_shared_key ​       "​$1"​ pre_shared_key 
-#/​etc/​ppp/​ip-up.d/​racoon +  ​config_get authentication_method "​$1"​ authentication_method 
-/​etc/​init.d/​racoon start +  ​config_get local_identifier ​     "​$1"​ local_identifier 
-</​code>​+  ​config_get remote_identifier ​    "​$1"​ remote_identifier
  
-Another way to reload racoon when the wan IP changes and we are not using ppp, is creating a script like this in /​etc/​hotplug.d/​iface/​35-racoon+  AuthenticationMethod=$authentication_method 
 +  LocalIdentifier=$local_identifier 
 +  RemoteIdentifier=$remote_identifier
  
-<code bash> +  RemoteGateway=$gateway 
-#!/bin/sh+  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
  
-ListenInterface() { +  Phase1Proposal=""​ 
-  ​local iface="​$1"​ +  ​config_list_foreach ​"​$1" ​p1_proposal ConfigPhase1 
-  ​if [ "​$INTERFACE" ​"$iface" ]; then +  ​Phase1Proposal=`echo $Phase1Proposal | cut -b 2-`
-    /​etc/​init.d/​racoon restart +
-  fi +
-}+
  
-RacoonInstance() { +  ​config_list_foreach "​$1" ​tunnel ConfigTunnel
-  ​config_list_foreach "​$1" ​listen ListenInterface+
 } }
  
-if [ "​$ACTION"​ = "​ifup"​ ]; then +PrepareEnvironment() { 
-  ​config_load racoon +  ​local debug
-  config_foreach RacoonInstance racoon +
-fi +
-</​code>​+
  
-===== Hardware performance =====+  for d in cacerts aacerts ocspcerts crls acerts; do 
 +    mkdir -p $FolderCerts/​$d 2>/​dev/​null 
 +  done
  
-In the times of broadband internet connections encryption and decryption speed of routers can limit throughput of VPN tunnelsCPU utilization maxes out at 100 percent and impacts other services of the device like a web serverIf you really want to go with a self made IPsec VPN on a cheap router you should consider some facts+  if [ ! -L /etc/ipsec.d ]; then 
 +    rm -rf /etc/ipsec.d 2>/​dev/​null 
 +    ln -s $FolderCerts /​etc/​ipsec.d 
 +  fi
  
-  ​* Older firewall devices with hardware accelerated VPN are sold for a few bucks on Ebay. Juniper Netscreen 5GT for example can easily reach a VPN throughput of 20 MBit/sec. Downside is that firmware updates are only possible with a Juniper support contract. So check twice for a bargain+  ​if [ ! -L /etc/ipsec.secrets ]; then 
-  * Firewall devices are build to support IPsec out of the boxA convenient web interface helps the administrator to build a tunnel in a few seconds. OpenWrt still lacks a standard LuCI config panel. If you only go with 1-5 VPN tunnels this should be no concern to you.+    rm /etc/ipsec.secrets 2>/​dev/​null 
 +    ln -s $FileSecrets /etc/ipsec.secrets 
 +  fi
  
-To find the right OpenWrt hardware for your VPN you should have a look at the following benchmark table. It is build on a simple test without any claim of perfection. Nevertheless the numbers are quite close to what you can expect from an AES 128/256 bit encrypted IPsec Tunnel connection with standard kernel modulesYou may notice that those numbers differ from what is written on the [[inbox:​benchmark.openssl|OpenSSL wiki page]]. But simply remember: **The tests over there do not include network traffic**If you want to add a new device onto the list check the encrpytion throughput using the following prerequisites+  if [ ! -L /etc/​strongswan.conf ]; then 
 +    rm /​etc/​strongswan.conf 2>/​dev/​null 
 +    ln -s $FileCommon /​etc/​strongswan.conf 
 +  fi
  
-  ​* Logon to a fast Linux machine ​ +  ​if [ ! -L /​etc/​ipsec.conf ]; then 
-  * Use a direct LAN connection to the router +    rm /​etc/​ipsec.conf 2>/​dev/​null 
-  * Ensure the router is idle +    ln -s $FileConn /​etc/​ipsec.conf 
-  ​* Transfer 100 MB of data using ssh +  ​fi
-  * Calculate the speed from the elapsed time. Throughput = 800 / SecondsElapsed+
  
-<​code>​ +  echo "# generated by /etc/init.d/​ipsec" ​$FileConn 
-ssh -2 -c aes128-cbc root@<​router>​ time dd if=/dev/zero bs=500000 count=200 ​/dev/null +  echo "​version ​2" ​$FileConn 
-ssh --c aes256-cbc root@<​routertime dd if=/dev/zero bs=500000 count=200 > /dev/null +  echo "# generated by /etc/init.d/ipsec" ​$FileSecrets
-</code>+
  
-You can have a look at the realtime traffic graph in a dry run afterwards to verify the speed. But do not open it during your test because it invalidates the results.+  config_get debug "​$1"​ debug 0
  
-^ CPU ^ MHz ^ tested device ^AES128 (s)^AES128 (MBit/s)^AES256 (s)^AES256 (MBit/s)^  +  echo "# generated by /etc/init.d/​ipsec"​ > $FileCommon 
-| MIPS 24k | 680 | [[toh:d-link:dir-825|D-Link DIR-825]] [[toh:​netgear:​wndr3700|Netgear WNDR3700]] |  28.2 |  28.5 |  32.4 |  24.6 | +  echo "​charon {" >> $FileCommon 
-| MIPS 24k | 400 | [[toh:​tp-link:​tl-wr703n|TP-Link TL-WR703N]] |  47.7 |  16.5 |  56.1 |  14.2 | +  echo " ​ load = aes des sha1 sha2 md5 gmp random nonce hmac stroke kernel-netlink socket-default updown"​ >> $FileCommon 
-| MIPS R3000 | 125 | [[toh:​asus:​wl500g|Asus WL-500g]] |  164.8 |  4.8 |  183.5 |  4.3 | +  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
  
 +}
  
-===== IPsec Tuning =====+CheckInstallation() { 
 +  if [ ! -x /​usr/​sbin/​ip ]; then 
 +    echo /​usr/​sbin/​ip missing 
 +    echo install with \"opkg install ip\" 
 +    exit 
 +  fi
  
-If you use a default OpenWrt installation you will discover that using the SHA1 hashing function will hit VPN performance. If you go for raw throughput MD5 can be a helpful alternative. One may remark that MD5 is [[http://​en.wikipedia.org/​wiki/​Md5#​Security|not very secure]] but for IPsec connections it should be enough as we are talking about hash values of encrypted data with a key that is changed [[doc:​uci:​racoon#​p2_proposal|every hour]] according to phase 2 proposals. A good tradeoff could be to choose AES256/SHA1 for phase 1 and AES128/MD5 for phase 2.  +  ​for f in aes 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
  
-Read on if you have some time and want to enhance your VPN speed. The kernel ​IPsec architecture relies on different crypto providers. E.g. if you build a tunnel with SHA1 checksums you must hava a module that can calculate those values. A look at /​proc/​crypto will reveal what modules are loaded and which algorithms they provide. The standard Linux Kernel modules are far from being optimized. At least with kernel 3.2 someone has taken care of [[http://git.kernel.org/?p=linux/kernel/git/​torvalds/​linux.git;a=commit;​h=1eb19a12bd2214cdcad5273d472b062a4ba97fa1|SHA1]]. Those of you that are on **MIPS big endian** machines can replace the default aes_generic.ko,​ sha_generic.ko,​ cbc.ko and md5.ko modules with a single assembler optimized [[https://sourceforge.net/projects/mcespi/files/​|mcespi.ko]]. Besides of being faster it has some nice characteristcs:​+  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 
 +}
  
-  * SHA1 calculation works on registers only +start() { 
-  ​* A lot of memcpy operations have been removed from MD5 and AES. +  ​CheckInstallation
-  * AES memory footprint is lowered from 16K to 8,2K +
-  * Avoid little endian byte swapping in AES +
-  * 21K module size in contrast to 4 modules with 45K+
  
-If you are on AR7161 you should ensure that you already have [[https://​dev.openwrt.org/​browser/​trunk/​target/​linux/​ar71xx/​patches-2.6.39/​910-unaligned_access_hacks.patch|unaligned access patch 1]] from trunk and the not yet implemented [[http://​patchwork.openwrt.org/​patch/​1721/​|unaligned access patch 2]]. It will free CPU from handling unaligned access expections so that you can reach these results:+  config_load ipsec 
 +  config_foreach PrepareEnvironment ipsec 
 +  config_foreach ConfigRemote remote
  
-^ OpenWrt ^ Device ^ AES256/SHA1 (MBit/s) ^ AES128/SHA1 (MBit/s)^ AES128/MD5 (MBit/​s)^ ​ +  config_load users 
-| trunk + mcespi.ko | MIPS 24K @ 680 MHz (AR7161) |  37.5 |  42.4 |  47.6 | +  ​config_foreach ConfigUser user
-| 10.03.1-rc6 | MIPS 24K @ 680 MHz (AR7161) |  18.0 |  19.6 |  30.3 |+
  
-The module is in early alpha development an the easyiest way to install it includes a few steps.+  /​usr/​sbin/​ipsec start 
 +}
  
-  * create a buildroot environment +stop() { 
-  * compile an image for your router once +  /usr/sbin/ipsec stop 
-  * put the mcespi.c into the the folder build_dir/​linux-<​arch>/​linux-<​X.Y.Z>/​crypto +}
-  * Include the line **obj-$(CONFIG_CRYPTO_AES+= mcespi.o** into build_dir/​linux-<​arch>/​linux-<​X.Y.Z>/​crypto/​Makefile +
-  ​* compile the image once again. +
-  * Afterwards you will find build_dir/linux-<​arch>/​linux-<​X.Y.Z>/​crypto/​mcespi.ko +
-  * Put mcespi.ko to your router into /​lib/​modules/<​X.Y.Z>​ +
-  * Load the module with insmod  +
-  * For automatic loading create a new /​etc/​modules.d/​09-crypto-mcespi with corresponding content. +
- +
-If you are not on MIPS big endian but you have at least kernel 2.6.39 you can head for SHA1 performance optimization. Download [[http://​wiki.openwrt.org/​_media/​doc/​howto/​sha1-optimized.c|sha_optimized.c]] and build it as a module. FIXME Ticket [[https://​dev.openwrt.org/​ticket/​10637|#​10637]] tries to implement that patch into trunk. At least on Atheros AR7161 platform and current trunk this leads to an oops. If you can help and find out why just put your feedback here or over there. ​ Note: On current trunk the default kernel is 3.3 and sha_optimized.c does not have to be backported anymore. +
- +
-<code bash> +
-mv 259-crypto_SHA1_3.2_backport.patch target/​linux/​generic/​patches-XXX +
-make target/linux/clean +
-make world+
 </​code>​ </​code>​
  
-===== OpenSSL Tuning =====+Before you start Charon with the web interface you should make a dry run from command line. This will show you if there are any errors in your generated configuration file **/​etc/​ipsec.conf**. Afterwards you can control startup behaviour with LuCI.
  
-While talking about performance optimization there is also room for some improvement for non-VPN encrpytion scenarios. With newer versions of OpenSSL more and more assembler encryption and decryption routines are included. [[http://cvs.openssl.org/​chngview?​cn=21708|Check-in 21708]] provides those for MIPS architecture and the 1.0.1 branch . Porting some of the assembler routines to OpenSSL 0.9.8p for ar71xx (Backfire 10.06.01-rc6) involves the following steps in the [[about:​toolchain|buildroot environment]]:​+{{:doc:​howto:​ipsec_daemon.png|}}
  
-  * Remove build_dir/​target_xxx/​openssl-0.9.8p/​* 
  
-  * Remove line OPENSSL_OPTIONS += no-perlasm from package/​openssl/​Makefile 
  
-  * Replace "​${no_asm}"​ with ":::​aes_cbc.o aes-mips.o:::::::"​ in file package/​openssl/​patches/​110-optimize-for-size.patch. Do not use quotation marks and ensure that you include those 10 colons. 
- 
-  * Start build process for first time with make package/​openssl/​compile V=99. This process will stop with an error. 
- 
-  * Copy crypto/​aes/​asm/​aes-mips.pl from OpenSLL 1.0.1 sources and store it into the newly created build_dir/​target_xxx/​openssl-0.9.8p/​crypto/​aes/​asm folder. ​ 
- 
-  * Modify build_dir/​target_xxx/​openssl-0.9.8p/​crypto/​aes/​Makefile and insert two lines (the second one starts with a tab) 
- 
-<​code>​ 
-aes-mips.s: asm/​aes-mips.pl 
-        $(PERL) asm/​aes-mips.pl > $@ 
-</​code>​ 
- 
-  * Restart build process with make package/​openssl/​compile V=99. It will complete without errors this time. 
- 
-  * Copy build_dir/​target_xxx/​openssl-0.9.8p/​libcrypto.so.0.9.8 to your router 
- 
-Comparing benchmark numbers before and afterwards with **openssl speed** gives a speedup of about 8% for aes-128-cbc and about 5% for aes-256-cbc. 
  
  
Line 561: Line 307:
 ===== What's next ===== ===== What's next =====
  
-After the basic setup you should ​continue with the [[vpn.ipsec.firewall|firewall modifications]].+After the basic setup you should ​make sure you understand ​the [[vpn.ipsec.performance|expected performance]] of low budget routers.
  
 ===== Tag ===== ===== Tag =====
  
 {{tag>​crypto}} {{tag>​crypto}}
 +
 +
doc/howto/vpn.ipsec.basics.1356102210.txt.bz2 · Last modified: 2012/12/21 16:03 by miceliux