-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathREADME
237 lines (201 loc) · 11.8 KB
/
README
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
Dependencies:
------------
Debian:
libmysql-client-dev
libtool
CentOS:
mysql-devel
libtool
Installation:
-------------
./autogen.sh
./configure
make
make install
Optionally, if you only ran make, you can copy the .so files
from src/.libs/ like:
$ sudo mkdir /etc/openvpn/mysql-auth
$ sudo cp -a src/.libs/libopenvpn-mysql-auth.so* /etc/openvpn/mysql-auth/
Then add the following line to your openvpn config file:
plugin /etc/openvpn/mysql-auth/libopenvpn-mysql-auth.so -c /etc/openvpn/mysql-auth/mysql-auth.conf
Options:
--------
1) openvpn config file
You can pass options to libopenvpn-mysql-auth.so:
-c /path/to/config default: mysql-auth.conf within openvpn directory (will depend on --cd argument passed to openvpn)
-d enable debugging info, default: no
2) mysql-auth.conf
The configuration must follow this rule:
option value
Available Options:
++++++++++++++++++
DB connection infos:
Required:
---------
hostname hostname to connect to (or "none" if using unix socket)
port port to connect to, default 0 (will connect to MySQL standard port)
login username used to establish connection to DB
password password used to establish connection to DB
db database to conenct to
s_path path to unix socket (or "none" if using TCP connection)
either hostname or s_path can be omitted, but at least one of them need to be set.
Once this is done, you will need to set the following option to authenticate users, check access permissions,
set up firewall rule, log connections....
There are all optional, and will enable different features if there are set or not.
In order to make this plugin as flexible as possible so it can adapt to any existing databases,
*expandable variable* are available, see below
Authentication:
---------------
User/Password authentication is done if at least *auth_user_pass_verify_query* is set up.
It goes through 3 steps:
- check user/password
- check user is allowed to access (if auth_user_pass_verify_user_access_query exists)
- if not yet allowed, check if groups the user belong to is allowed to access
(auth_user_pass_verify_group_access_query)
* auth_user_pass_verify_query
Query to check if user/password matches. To succeed, 1 and only
1 row must be returned. The value of 1st field in row will be used
as {{user_id}} expandable variable
ex: SELECT id FROM users WHERE username={{escaped_username}} AND password=SHA1('{{escaped_password}}')
* auth_user_pass_verify_user_access_query
After a user is authenticated, this query will check if the user is
allowed to access the service.
If omitted, no user_access check will be performed.
Access will be granted if at least 1 row is returned
ex: SELECT access_id FROM user_access WHERE user_access.user_id = {{user_id}}
* auth_user_pass_verify_group_access_query
Same as above, but for groups. Will only be called:
if defined and user access did not succeed
OR
if defined and user_access_query was not defined
Packet Filtering:
----------------
Packet filtering can be enabled in 2 manners:
1) using a single query to get default clients/subnets rules and clients/subnets rules
2) using a query for each item needed, namely default clients rules, default subnets rules, clients rules, subnets rules
1) is used if enable_pf_user_rules_query or enable_pf_group_rules_query is defined
2) is used if:
- enable_pf_clients_user_default_rules_query, enable_pf_subnets_user_default_rules_query, enable_pf_clients_user_rules_query AND enable_pf_subnets_user_rules_query are defined
OR
- enable_pf_clients_group_default_rules_query, enable_pf_subnets_group_default_rules_query, enable_pf_clients_group_rules_query AND enable_pf_subnets_group_rules_query are defined
If either enable_pf_user_rules_query or enable_pf_group_rules_query is defined, query from 2) will not be tried.
When resolving the rules that apply to a specific VPN connection, during auth-user-pass-verify, the plugin will first attempt to get the rules from the *user* rules,
If it did not succeed, the plugin will try the rules for the *group* .
Finally, if after this, the plugin did not manage to get rules for that specific connections, the default values from
default_pf_rules_clients, default_pf_rules_subnets, pf_rules_clients, pf_rules_subnets will be used.
By default, these options have the following default:
default_pf_rules_clients (DROP)
default_pf_rules_subnets (DROP)
pf_rules_clients (NULL)
pf_rules_subnets (NULL)
Here are the options that are available for packet filtering:
- Service wide:
* default_pf_rules_clients
If no default client behaviour for this specific connection
could be found, this value will be used.
Accepted values: ACCEPT,DROP
Default: DROP
* default_pf_rules_subnets
If no default subnets behaviour for this specific connection
could be found, this value will be used.
Accepted values: ACCEPT,DROP
Default: DROP
* pf_rules_clients
If no clients rules for this specific connection could be found this will be used
Accepted value: any text that follow Packet Filtering grammar (see below)
Default: NULL
* pf_rules_subnets
If no subnets rules for this specific connection could be found this will be used
Accepted value: any text that follow Packet Filtering grammar (see below)
Default: NULL
- Single query
enable_pf_user_rules_query
Query that will retrieve PF rules for that connection.
The 4 first fields of MySQL results will be used and must follow
this order: default_clients_rule, default_subnets_rule, clients_rules, subnets_rules
Ex: SELECT f.default_clients, f.default_subnets, f.rules_clients, f.rules_subnets FROM firewall_rules f, user_firewall_rules uf WHERE f.firewall_rule_id=uf.firewall_rule_id AND uf.user_id={{user_id}}
enable_pf_group_rules_query
Query that will retrieve PF rules for that connection.
The 4 first fields of MySQL results will be used and must follow
this order: default_clients_rule, default_subnets_rule, clients_rules, subnets_rules
Ex: SELECT f.default_clients, f.default_subnets, f.rules_clients, f.rules_subnets FROM firewall_rules f, group_firewall_rules gf, group_users gu WHERE f.firewall_rule_id=gf.firewall_rule_id AND gf.group_id=gu.group_id AND gu.user_id={{user_id}}
default_clients and default_subnets MUST BE ACCEPT or DROP (will default to drop if unknown value)
clients_rules and subnets_rules must follow Packet Filtering grammar (see below). If NULL, no rules will be used.
- Multiple queries
In multiple query mode, each query must return its value in first row, first field.
The options are:
* enable_pf_clients_user_default_rules_query
ex: SELECT f.default_clients FROM firewall_rules f, user_firewall_rules uf WHERE f.firewall_rule_id=uf.firewall_rule_id AND uf.user_id={{user_id}}
* enable_pf_clients_user_rules_query
ex: SELECT f.rules_clients FROM firewall_rules f, user_firewall_rules uf WHERE f.firewall_rule_id=uf.firewall_rule_id AND uf.user_id={{user_id}}
* enable_pf_subnets_user_default_rules_query
ex: SELECT f.default_subnets FROM firewall_rules f, user_firewall_rules uf WHERE f.firewall_rule_id=uf.firewall_rule_id AND uf.user_id={{user_id}}
* enable_pf_subnets_user_rules_query
ex: SELECT f.rules_subnets FROM firewall_rules f, user_firewall_rules uf WHERE f.firewall_rule_id=uf.firewall_rule_id AND uf.user_id={{user_id}}
AND
* enable_pf_clients_group_default_rules_query
ex: SELECT f.default_clients FROM firewall_rules f, group_firewall_rules gf, group_users gu WHERE f.firewall_rule_id=gf.firewall_rule_id AND gf.group_id=gu.group_id AND gu.user_id={{user_id}}
* enable_pf_clients_group_rules_query
ex: SELECT f.rules_clients FROM firewall_rules f, group_firewall_rules gf, group_users gu WHERE f.firewall_rule_id=gf.firewall_rule_id AND gf.group_id=gu.group_id AND gu.user_id={{user_id}}
* enable_pf_subnets_group_default_rules_query
ex: SELECT f.default_subnets FROM firewall_rules f, group_firewall_rules gf, group_users gu WHERE f.firewall_rule_id=gf.firewall_rule_id AND gf.group_id=gu.group_id AND gu.user_id={{user_id}}
* enable_pf_subnets_group_rules_query
ex: SELECT f.rules_subnets FROM firewall_rules f, group_firewall_rules gf, group_users gu WHERE f.firewall_rule_id=gf.firewall_rule_id AND gf.group_id=gu.group_id AND gu.user_id={{user_id}}
NOTE: At most one row should be returned. In case more than one row is returned, the result will be discarded.
That would mean that in case of "group" rules, the user can belong to only 1 group
Expandable Variables:
+++++++++++++++++++++
Expandable variable should be surrounded by double curly brackets "{{var}}" in the queries, the following
are *potentially* available depending on the callback being called:
time_now actual unix timestamp (always available)
username username sent by client, start to be available when OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY
callback is triggered
password only available in OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY
escaped_username
escaped_password same as above, but SQL safe
trusted_ip IP the client is connecting with (available with OPENVPN_PLUGIN_CLIENT_CONNECT)
trusted_port Port the client is conencting from (available with OPENVPN_PLUGIN_CLIENT_CONNECT)
time_unix Timestamo at which client successfully connected (available with OPENVPN_PLUGIN_CLIENT_CONNECT)
ifconfig_pool_remote_ip
VPN IP given to client (available with OPENVPN_PLUGIN_CLIENT_CONNECT)
time_duration Time the connection lasted (available with OPENVPN_PLUGIN_CLIENT_DISCONNECT)
bytes_sent Total number of bytes sent to client during VPN session (available with OPENVPN_PLUGIN_CLIENT_DISCONNECT)
bytes_received Total number of bytes received from client during VPN session (available with OPENVPN_PLUGIN_CLIENT_DISCONNECT)
More detailed info from:
man openvpn
in section "Environmental Variables"
Callback calls:
+++++++++++++++
To check in what order the callback will be called, see
http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn/openvpn-plugin.h
Packet Filtering grammar (from openvpn-plugin.h)
------------------------------------------------
* Packet filter file grammar:
*
* [CLIENTS DROP|ACCEPT]
* {+|-}common_name1
* {+|-}common_name2
* . . .
* [SUBNETS DROP|ACCEPT]
* {+|-}subnet1
* {+|-}subnet2
* . . .
* [END]
*
* Subnet: IP-ADDRESS | IP-ADDRESS/NUM_NETWORK_BITS
*
* CLIENTS refers to the set of clients (by their common-name) which
* this instance is allowed ('+') to connect to, or is excluded ('-')
* from connecting to. Note that in the case of client-to-client
* connections, such communication must be allowed by the packet filter
* configuration files of both clients.
*
* SUBNETS refers to IP addresses or IP address subnets which this
* instance may connect to ('+') or is excluded ('-') from connecting
* to.
*
* DROP or ACCEPT defines default policy when there is no explicit match
* for a common-name or subnet. The [END] tag must exist. A special
* purpose tag called [KILL] will immediately kill the client instance.
* A given client or subnet rule applies to both incoming and outgoing
* packets.