-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathufw-vpn.php
executable file
·194 lines (164 loc) · 4.14 KB
/
ufw-vpn.php
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#!/usr/bin/env php
<?php
/**
* Script to create UFW rules to allow VPN connections
*
* To-do items
*
* Validate output of getVpnIps, report an error if necessary
* Allow the 443 port to be changed or removed using a console option
* Add shell comment explaining what the script does
* Add shell comment about when it was generated
* Add shell comment how many rules have been generated
*/
use UfwVpn\Diff;
$root = __DIR__;
require_once $root . '/src/bootstrap.php';
/**
* IP addresses to ignore
*
* This was originally added to filter out local addresses parsed from nslookup;
* now I am using PHP's own DNS read feature, it is less necessary. However it
* may be useful to add an --ignore parameter in the future, so I will keep
* this for now.
*/
function getIgnoreIpList()
{
return [];
}
/**
* Removes a set of IP addresses from another set
*/
function filterList(array $allow, array $deny)
{
return array_diff($allow, $deny);
}
/**
* Effectively does an nslookup on the supplied address
*
* @todo Replace this with the Vpn class
*/
function getVpnIps($vpnAddress) {
$ips = gethostbynamel($vpnAddress);
return $ips;
}
function getAllowedIpList($vpnAddress)
{
$allow = getVpnIps($vpnAddress);
if (!is_array($allow))
{
throw new \Exception(
sprintf("Could not fetch IP list from `%s`", $vpnAddress)
);
}
$deny = getIgnoreIpList();
$ips = filterList($allow, $deny);
return $ips;
}
function generateCommands($ips, $subCommand = '')
{
$commands = [];
foreach ($ips as $ip)
{
$command = "ufw {$subCommand} allow out to {$ip} port 443";
$commands[] = $command;
}
return $commands;
}
/**
* Returns an array of "allow" commands for a given set of IP addresses
*
* @param array $ips
* @return array
*/
function generateAllowCommands($ips)
{
return generateCommands($ips);
}
/**
* Returns an array of "delete" commands for a given set of IP addresses
*
* @param array $ips
* @return array
*/
function generateDeleteCommands($ips)
{
return generateCommands($ips, "delete");
}
/**
* Returns the smallest number of commands to bring the rules up to date
*
* @return array
*/
function generateDiffCommands($newIps, $oldIps)
{
$diff = new Diff();
$changes = $diff->compare($oldIps, $newIps);
$allowCommands = generateAllowCommands($changes['add']);
$deleteCommands = generateDeleteCommands($changes['remove']);
return array_merge($allowCommands, $deleteCommands);
}
function processRequest($vpnAddress, $command)
{
$commands = null;
switch ($command)
{
case 'add':
$commands = generateAllowCommands(getAllowedIpList($vpnAddress));
break;
case 'delete':
$commands = generateDeleteCommands(getAllowedIpList($vpnAddress));
break;
case 'diff':
$firewall = new \UfwVpn\Firewall();
$oldIps = $firewall->getConfiguration();
$commands = generateDiffCommands(getAllowedIpList($vpnAddress), $oldIps);
break;
default:
echo "Not a valid command\n";
}
if ($commands)
{
echo "#!/bin/bash\n\n";
sort($commands);
echo implode("\n", $commands) . "\n";
}
}
function printSyntax()
{
echo <<<SYNTAX
This script is used to generate UFW firewall setup/teardown scripts to
allow VPN connections through.
Syntax:
ufw-vpn.php <vpn-url> <add|diff|delete>
Where:
vpn-url is the address of your VPN, e.g. uk.myexamplevpn.net
"add" specifies that an add script is to be generated
"diff" specifies that a differencess script is to be generated
"delete" specifies that a rule delete script is to be generated
Example:
ufw-vpn.php uk.myexamplevpn.net add > add-rules.sh
chmod u+x add-rules.sh
sudo ./add-rules.sh
SYNTAX;
}
$vpnAddress = isset($argv[1]) ? $argv[1] : '';
$command = isset($argv[2]) ? $argv[2] : '';
if ($vpnAddress && $command)
{
try
{
processRequest($vpnAddress, $command);
}
catch (\Exception $e)
{
echo sprintf(
"Error: %s\n",
$e->getMessage()
);
}
}
else
{
printSyntax();
}