Differences

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

Link to this comparison view

wiki:old:idhal [2013/07/10 22:16] (current)
Line 1: Line 1:
 +====== Mechanism ======
 +===== Secured update procedure =====
 +At the very first boot, a virtual node gets the server GPG public key and never get it again. Then, periodically (at boot and from cron), the virtual node makes an http query to get an update script from the server. The server signs it and the node checks the signature of the script before executing it locally:
 +
 +[[Image:​idhal_updates.png]]
 +===== The update script =====
 +The script looks like:
 +
 +<​code>​
 + ​UPDATES="/​var/​lib/​idhal-updates"​
 + # Update #000
 + if [! -f $UPDATES/​000 ]
 + then
 +    #
 +    # do update 000
 +    #
 +    touch $UPDATES/​000
 + fi
 + # Update #001
 + if [! -f $UPDATES/​001 ]
 + then
 +    #
 +    # do update 001
 +    #
 +    touch $UPDATES/​001
 + fi
 + # and so on...
 + ​-----BEGIN PGP SIGNATURE-----
 + ​Version:​ GnuPG v1.4.6 (GNU/Linux)
 + ​iD8DBQFL6V1yWciA6gGguMwRAqU+AJ93IOh+lxAsuYFUUVlrsM6HGorUJACff4ko
 + ​s/​bE76z4S4MzZZ1EkN+UyGk ======
 +====== wfbT
 + ​-----END PGP SIGNATURE-----</​code>​
 +
 +The key is that an update (a scriptlet) is executed only once.
 +
 +===== The first update sets up the tunnel =====
 +==== Update ====
 +<​code>​
 + if [! -f $UPDATES/​000 ]
 + then
 +   wget -q -O /​tmp/​gen_certif http://​129.88.70.253:​8080/​cgi-bin/​gen_certif?​idhaltype=vnode || exit 1
 +   chmod 700 /​tmp/​gen_certif
 +   /​tmp/​gen_certif || exit 1
 +   rm -f /​tmp/​gen_certif
 +   /​etc/​init.d/​openvpn stop
 +   /​etc/​init.d/​openvpn start
 +   sleep 10
 +   touch $UPDATES/​000
 + ​fi</​code>​
 +====  gen_certif cgi-bin script ====
 +This script generates a unique ID and a certificate for the virtual node. Then, it outputs a bash script that makes an Openvpn configuration and copies the certificate. ​
 +
 +<​code>​
 + #​!/​usr/​bin/​ruby
 + ​require '​fileutils'​
 + ​require "​cgi"​
 + cgi = CGI.new
 + ​idhaltype = cgi['​idhaltype'​] ​
 + ​EASY_RSA_DIR="/​etc/​openvpn/​easy-rsa" ​
 + def get_next_id
 +   id=0
 +   ​keys_dir=Dir.new(EASY_RSA_DIR + "/​keys"​)
 +   ​keys_dir.each do |file|
 +     if client_id=file.scan(/​client(\\d+)\\.crt/​)[0]
 +       if client_id[0].to_i > id
 +         ​id=client_id[0].to_i
 +       end
 +     end
 +   end
 +   ​return id+1
 + end
 + ​Dir::​chdir(EASY_RSA_DIR) ​
 + ​id=get_next_id
 + ​system("​. ./vars > /dev/null && ./pkitool client#{id} > /dev/null 2>&​1"​)
 + f = File.new("#​{easy_rsa_dir}/​keys/​client#​{id}.type", ​ "​w"​)
 + ​f.puts idhaltype
 + ​f.close
 + puts "​Content-type:​ text/​plain"​
 + puts
 + puts "#​!/​bin/​bash"​
 + puts "if [-d /​etc/​openvpn ] ; then"
 + puts "cat > /​etc/​openvpn/​vpns.conf << EOF
 + ​client
 + dev tun
 + proto tcp
 + ​remote 129.88.70.253 4242
 + ca ca.crt
 + cert client.crt
 + key client.key
 + ​keepalive 10 60
 + ​cipher none
 + up /​etc/​openvpn/​update-resolv-conf
 + down /​etc/​openvpn/​update-resolv-conf
 + ​EOF"​
 + puts "cat > /​etc/​openvpn/​client.crt << EOF"
 + ​IO.foreach("#​{easy_rsa_dir}/​keys/​client#​{id}.crt"​) { |line| puts line }
 + puts "​EOF" ​
 + puts "cat > /​etc/​openvpn/​client.key << EOF"
 + ​IO.foreach("#​{easy_rsa_dir}/​keys/​client#​{id}.key"​) { |line| puts line }
 + puts "​EOF" ​
 + puts "chmod 600 /​etc/​openvpn/​client.key" ​
 + puts "​fi"</​code>​
 +
 +===== The VPN server side configuration =====
 +==== Openvpn ====
 +<​code>​
 + port 4242
 + proto tcp
 + dev tun0
 + ca ca.crt
 + cert server.crt
 + key server.key
 + dh dh1024.pem
 + ​server 10.134.0.0 255.255.0.0
 + #​ifconfig-pool-persist ipp.txt
 + ​keepalive 10 120
 + ​max-clients 1000
 + ​persist-key
 + ​persist-tun
 + ​status /​var/​log/​openvpn-status.log
 + # Script where we create/​activate OAR nodes
 + ​client-connect /​etc/​openvpn/​client-up.bash
 + ​client-disconnect /​etc/​openvpn/​client-down.bash
 + # G5K Routes pushing
 + push "route 129.88.70.0 255.255.255.192"​
 + ​[[...]]
 + # DNS pushing
 + push "​dhcp-option DNS 129.88.70.61"​
 + push "​dhcp-option DNS grenoble.grid5000.fr"</​code>​
 +==== DNS ====
 +Every virtual ip address is statically declared into DNS like this example:
 +<​code>​
 + ​vnode-7-38 ​             A       ​10.134.7.38</​code>​
 +===== OAR server =====
 +Resources are added automatically when new tunnels come up. Resources are disabled (but not removed) when tunel goes down. This is made inside the client-up/​down openvpn scripts:
 +  *  /​etc/​openvpn/​client-up.bash:​
 +<​code>​
 + #​!/​bin/​bash
 + set -e
 + ​NODE_NAME=`host -t A $ifconfig_pool_remote_ip |awk -F": " '{if ($1=="​name"​) print $2}'`
 + ​CLIENT_NAME=`host -t A $trusted_ip |awk -F": " '{if ($1=="​name"​) print $2}'`
 + ​NODE=`oarnodes --sql "​ip='​$ifconfig_pool_remote_ip'"​`
 + if [[|"​$NODE"​ = ""​ ]]
 + then
 +   ​oarnodesetting -a -h "​$NODE_NAME"​ -p "​ip=$ifconfig_pool_remote_ip"​
 + fi
 + ​HIDHAL_TYPE=`cat /​etc/​openvpn/​easy-rsa/​keys/​$common_name.type 2>/​dev/​null || true`
 + if ["​$HIDHAL_TYPE"​ != ""​]
 + then
 +   ​oarnodesetting -p "​idhaltype=$HIDHAL_TYPE"​ \\
 +                  -p "​cluster=$HIDHAL_TYPE"​ -h "​$NODE_NAME"​
 + fi
 + ​oarnodesetting -p "​idhalcn=$common_name"​ \\
 +                -p "​idhalclientip=$trusted_ip"​ \\
 +               -p "​idhalconnectedsince=`date`"​ \\
 +               -p "​idhalclientname=$CLIENT_NAME"​ \\
 +               -h $NODE_NAME
 + echo "/​usr/​local/​sbin/​send_root_key.sh $NODE_NAME"​ | at now + 1 minute
 + ​oarnodesetting -s Alive -h "​$NODE_NAME"</​code>​
 +
 +  *   /​etc/​openvpn/​client-down.bash
 +<​code>​
 + #​!/​bin/​bash
 + set -e
 + ​NODE_NAME=`host -t A $ifconfig_pool_remote_ip |awk -F": " '{if ($1=="​name"​) print $2}'` >> /tmp/down
 + ​oarnodesetting -s Absent -h "​$NODE_NAME"​ >> /tmp/down
 + echo "​$NODE_NAME"​ >> /​tmp/​down</​code>​
 +
 +Here is a sample resource:
 +<​code>​
 + 168
 +        network_address : vnode-2-98.grenoble.grid5000.fr
 +        properties : besteffort=YES,​cluster=vnode,​cpuset=0,​deploy=NO,​desktop_computing=NO,​idhalclientip=152.77.57.112,​idhalclientname=browalle.ujf-grenoble.fr,​idhalcn=client317,​idhalconnectedsince=Thu Jul  3 20:32:35 CEST 2008,​idhaltype=vnode,​ip=10.134.2.98,​network_address=vnode-2-98.grenoble.grid5000.fr,​type=default
 +        state : Absent</​code>​
 +
 +====== Caveats ======
 +The main problem with this solution is that every communication between the nodes is made through the VPN. Actually, we want that the nodes that are on a same LAN or routed network, use their local interface to communicate directly. The solution might be on DNS side...
  
wiki/old/idhal.txt ยท Last modified: 2013/07/10 22:16 (external edit)
Recent changes RSS feed GNU Free Documentation License 1.3 Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki