Enable @ref{Encless, encryptionless mode}.
@item -up
-Optional path to script that will be executed after connection is
-established. Interface name will be given to it as a first argument.
+Optional path to @ref{Scripts, script} that will be executed after
+connection is established. Interface name will be given to it as a first
+argument.
@item -down
Same as @option{-up} above, but it is executed when connection is lost,
@verbatim
client% cat > up.sh <<EOF
#!/bin/sh
-dhclient $1
-rtsol $1
+dhclient $GOVPN_IFACE
+rtsol $GOVPN_IFACE
EOF
client% chmod +x up.sh
@end verbatim
* Timeout::
* Time synchronization: Timesync.
* Network transport: Network.
+* Scripts::
* Proxy::
* Maximum Transmission Unit: MTU.
* Statistics: Stats.
@include timeout.texi
@include timesync.texi
@include netproto.texi
+@include scripts.texi
@include proxy.texi
@include mtu.texi
@include stats.texi
@node Новости
@section Новости
+@node Релиз 5.7
+@subsection Релиз 5.7
+@itemize
+@item Имя TAP интерфейса и адрес удалённой стороны теперь передаются в
+up- и down- скрипты через переменные окружения.
+@end itemize
+
@node Релиз 5.6
@subsection Релиз 5.6
@itemize
See also this page @ref{Новости, on russian}.
+@node Release 5.7
+@section Release 5.7
+@itemize
+@item TAP interface name and remote peer's address are passed to up- and
+down- scripts through environment variables.
+@end itemize
+
@node Release 5.6
@section Release 5.6
@itemize
--- /dev/null
+@node Scripts
+@subsection Scripts
+
+Up- and down- scripts used as a hook executed when connection is either
+established or lost. Following environment variables are set during
+their execution:
+
+@table @code
+
+@item GOVPN_REMOTE
+Remote peer's address. In client mode it is server's address.
+
+@item GOVPN_IFACE
+TAP interface name. In server mode this can be empty: that means that
+script must output its name as the first line to stdout.
+
+@end table
At least one of either @code{iface} or @code{up} must be specified. If
you specify @code{iface}, then it will be forcefully used to determine
-what TAP interface will be used. If it is not specified, then up-script
-must output interface's name to stdout (first output line).
+what TAP interface will be used. If it is not specified, then
+up-@ref{Scripts, script} must output interface's name to stdout
+(first output line).
For example up-script can be just @code{echo tap10}, or more advanced
like the following one:
-
@verbatim
#!/bin/sh
$tap=$(ifconfig tap create)
close(rehandshaking)
close(termination)
}
- govpn.ScriptCall(*downPath, *ifaceName)
+ govpn.ScriptCall(*downPath, *ifaceName, *remoteAddr)
}
log.Println("Handshake completed")
knownPeers = govpn.KnownPeers(map[string]**govpn.Peer{*remoteAddr: &peer})
if firstUpCall {
- go govpn.ScriptCall(*upPath, *ifaceName)
+ go govpn.ScriptCall(*upPath, *ifaceName, *remoteAddr)
firstUpCall = false
}
hs.Zero()
log.Println("Handshake completed")
knownPeers = govpn.KnownPeers(map[string]**govpn.Peer{*remoteAddr: &peer})
if firstUpCall {
- go govpn.ScriptCall(*upPath, *ifaceName)
+ go govpn.ScriptCall(*upPath, *ifaceName, *remoteAddr)
firstUpCall = false
}
hs.Zero()
heartbeat.Stop()
}
-func callUp(peerId *govpn.PeerId) (string, error) {
+func callUp(peerId *govpn.PeerId, remoteAddr string) (string, error) {
ifaceName := confs[*peerId].Iface
if confs[*peerId].Up != "" {
- result, err := govpn.ScriptCall(confs[*peerId].Up, "")
+ result, err := govpn.ScriptCall(confs[*peerId].Up, ifaceName, remoteAddr)
if err != nil {
log.Println("Script", confs[*peerId].Up, "call failed", err)
return "", err
go govpn.ScriptCall(
confs[*ps.peer.Id].Down,
ps.tap.Name,
+ ps.peer.Addr,
)
ps.terminator <- struct{}{}
}
kpLock.Unlock()
log.Println("Rehandshake processed:", peer.Id.String())
} else {
- ifaceName, err := callUp(peer.Id)
+ ifaceName, err := callUp(peer.Id, peer.Addr)
if err != nil {
peer = nil
break
log.Println("Rehandshake processed:", peer.Id.String())
} else {
go func(addr string, peer *govpn.Peer) {
- ifaceName, err := callUp(peer.Id)
+ ifaceName, err := callUp(peer.Id, peer.Addr)
if err != nil {
return
}
EtherSize = 14
MTUMax = 9000 + EtherSize + 1
MTUDefault = 1500 + EtherSize + 1
+
+ ENV_IFACE = "GOVPN_IFACE"
+ ENV_REMOTE = "GOVPN_REMOTE"
)
var (
// You have to specify path to it and (inteface name as a rule) something
// that will be the first argument when calling it. Function will return
// it's output and possible error.
-func ScriptCall(path, ifaceName string) ([]byte, error) {
+func ScriptCall(path, ifaceName, remoteAddr string) ([]byte, error) {
if path == "" {
return nil, nil
}
if _, err := os.Stat(path); err != nil && os.IsNotExist(err) {
return nil, err
}
- out, err := exec.Command(path, ifaceName).CombinedOutput()
+ cmd := exec.Command(path)
+ cmd.Env = append(cmd.Env, ENV_IFACE+"="+ifaceName)
+ cmd.Env = append(cmd.Env, ENV_REMOTE+"="+remoteAddr)
+ out, err := cmd.CombinedOutput()
if err != nil {
log.Println("Script error", path, err, string(out))
}
# List of parameters passed through environment
# - reason -- why this script is called:
# pre-init, connect, disconnect
-# - VPNGATEWAY -- public address of vpn gateway
-# - TAPDEV -- tap device
+# - GOVPN_REMOTE -- public address of VPN gateway
+# - GOVPN_IFACE -- tap device
# - INTERNAL_IP4_ADDRESS -- e.g. 172.0.0.2/24
# - INTERNAL_IP4_GATEWAY -- e.g. 172.0.0.1
set_up_dev() {
- ip tuntap add dev $TAPDEV mode tap
+ ip tuntap add dev $GOVPN_IFACE mode tap
}
tear_down_dev() {
- ip tuntap del dev $TAPDEV mode tap
+ ip tuntap del dev $GOVPN_IFACE mode tap
}
do_connect() {
local OLDGW=$(ip route show 0/0 | sed 's/^default//')
- ip link set dev $TAPDEV up
- ip addr add $INTERNAL_IP4_ADDRESS dev $TAPDEV
- ip route add $VPNGATEWAY $OLDGW
- ip route add 0/1 via $INTERNAL_IP4_GATEWAY dev $TAPDEV
- ip route add 128/1 via $INTERNAL_IP4_GATEWAY dev $TAPDEV
+ ip link set dev $GOVPN_IFACE up
+ ip addr add $INTERNAL_IP4_ADDRESS dev $GOVPN_IFACE
+ ip route add $GOVPN_REMOTE $OLDGW
+ ip route add 0/1 via $INTERNAL_IP4_GATEWAY dev $GOVPN_IFACE
+ ip route add 128/1 via $INTERNAL_IP4_GATEWAY dev $GOVPN_IFACE
}
do_disconnect() {
- ip route del $VPNGATEWAY
+ ip route del $GOVPN_REMOTE
}