-
Notifications
You must be signed in to change notification settings - Fork 29
/
vpnchain.sh
131 lines (106 loc) · 3.77 KB
/
vpnchain.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/bin/bash
##
## CONFIG SECTION:
##
# Config array number is used for ordering chain
config[1]=config1.ovpn
config[2]=config2.ovpn
#config[3]=config3.ovpn
#config[4]=config4.ovpn
verbose=1 # verbose level; from 0 to 6
enable_firewall=1 # Block outgoing traffic except openvpn servers (HIGHLY RECOMMENDED)
block_ipv6=1
##
## Don't change anything bellow unless you know what you are doing
##
clear
## Code begins:
# Some vars:
firewall_rules_file='./.vpnchain.firewall'; # set firewall rules file
source './functions.vpnchain' # read functions file
if [ "$1" = "flush" ]; then
FIREWALL flush
rm $firewall_rules_file
exit
fi
if [ $enable_firewall -gt 0 ] && [ -f "$firewall_rules_file" ]; then
FIREWALL flush
rm $firewall_rules_file
fi
if [ $block_ipv6 -gt 0 ]; then
echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6
fi
# execute function on exit
trap " ON_EXIT " INT TERM
config_length=${#config[@]};
i=1
tun_array=()
# Loop for configs array:
while [ $i -le $config_length ]; do
SHOW info "Using config [$i]: ${config[$i]}"
# Parse Client's remote server ip from config
client_remote_ip=$(grep -v '^#' ${config[$i]} | grep -v '^$' | grep remote\ | awk '{print $2}' | head -n 1)
SHOW info "Client remote ip: $client_remote_ip"
# For routing purposes we need to get next Client's remote server ip from next config
let next=$i+1;
if [ "$next" -le "$config_length" ]; then
next_client_remote_ip=$(grep -v '^#' ${config[$next]} | grep -v '^$' | grep remote\ | awk '{print $2}' | head -n 1)
SHOW info "Next client remote ip: $next_client_remote_ip"
else # leave var empty if there is no next config left
next_client_remote_ip=
fi
# Get default gateway for routing purposes
default_gateway=$(route -nee | awk 'FNR==3 {print $2}')
SHOW info "Using default gateway: $default_gateway"
# Check if we don't have last config or if there is only one config set;
# or else we don't need to provide any route directly to openvpn command. In that case all needed routing is done
# by vpnchain_helper.sh script
if [[ "$i" -eq "1" || "$config_length" -eq "1" ]]; then
openvpn_route="--route $client_remote_ip 255.255.255.255 $default_gateway"
else
openvpn_route=
fi
# Check if we have last config and if so, we provide different arguments for vpnchain_helper.sh script;
# or else we proceed normaly
if [ "$i" -eq "$config_length" ]; then
openvpn_up="vpnchain_helper.sh -u -l"
openvpn_down="vpnchain_helper.sh -d -l"
else
openvpn_up="vpnchain_helper.sh -u $next_client_remote_ip"
openvpn_down="vpnchain_helper.sh -d $next_client_remote_ip"
fi
# We need to get available tun device (that is not currently in use). Yes, openvpn can detect this automaticaly,
# but in our case we need to assign them manualy, because we need to put them in array for function that checks
# if all chains are connected. Maybe this can be done in more elegant way...
GET_TUN
if [ -z "$tun_array" ]; then
tun_array=( "$client_tun" )
else
tun_array=( "${tun_array[@]}" "$client_tun" )
fi
# Block all outgoing traffic except openvpn servers
if [ $enable_firewall -gt 0 ]; then
if [[ -n "$client_remote_ip" && "$i" -eq "1" ]]; then
FIREWALL add "-d $client_remote_ip -j ACCEPT"
fi
fi
# Start vpn connection
CONNECT
# Wait for Client to connect
TUN=`cat /proc/net/dev | grep -o $client_tun`;
while [ -z "$TUN" ]
do
SHOW info "Waiting for $client_tun..."
TUN=`cat /proc/net/dev | grep -o $client_tun`
sleep 5s;
done
# If all connections done, then we jump to chains connection checking function
if [ "$i" -eq "$config_length" ]; then
CHECK_CONNECTION
fi
let i++;
done
if [ $block_ipv6 -gt 0 ]; then
echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6
fi
exit