Blame

09eeb6 Samuli Seppänen 2025-02-28 15:35:21 1
# OpenVPN as non privileged user 
2
3
**NOTE: this article is outdated. It has been possible for years to run OpenVPN-GUI as a normal Windows user without admin-level privileges.**
4
5
The entire process that is described here [http://youtu.be/DxQaVf8iAJk|can be watched at youtube here].
6
These days a lot of users do not work as privileged user, they do not have administrative rights on their computers. If such a user needs to establish an OpenVPN connection (OpenVPN and OpenVPN-GUI are already installed) the connection will be established but the necessary routes are not set. Setting routes in Windows has some requirements:
7
8
```
9
----------------------------------------
10
| Operating System | ADM | NCO | RHP |
11
----------------------------------------
12
| Windows XP | X | | |
13
----------------------------------------
14
| Windows XP | | X | |
15
----------------------------------------
16
| Windows 7 | X | | |
17
----------------------------------------
18
| Windows 7 | | X | X |
19
----------------------------------------
20
| Windows 8 | X | | |
21
----------------------------------------
22
| Windows 8 | | X | X |
23
----------------------------------------
24
```
25
26
```
27
RHP = run with highest privileges but in context of a non-administrative user
28
ADM = Member of group "Administrators"
29
NCO = Member of group "Network Configuration Operators"
30
```
31
32
Note: Since Windows 7 being **only** a member of the **"Network Configuration Operators"** group **is not enough** to be able to set routes.
33
34
There are some OpenVPN-Clients that are able to establish connections and setting routes without administrative privileges but they are either unstable [[http://sourceforge.net/projects/securepoint/|SecurePoint SSL VPN]]) or do not have all necessary features ([[http://openvpn-mi-gui.inside-security.de/|OpenVPN MI GUI]]). They both use a service (running as administrator) and communicate with the service from user mode. But sometimes your configuration does not allow "service mode" and so you are stuck.
35
36
## Solution for Windows XP
37
Add the non privileged user (e.g. bob) to the group
38
39
```
40
Network Configuration Operators
41
```
42
43
You can do this with the following command
44
45
```
46
net localgroup "Network Configuration Operators" bob /add
47
```
48
49
and OpenVPN-GUI will perfectly work without administrative privileges.
50
51
**This solution does no longer work with Windows 7 and above.**
52
53
## New and working solution for Windows 7 (and above)
54
In July 2013 I had an idea. Why not creating a scheduled task at logon of any user that **automatically** creates another Scheduled Task for the non privileged user that is currently logging on. This **automatically** created task will put the user in the group "Network Configuration Operators" and then start OpenVPN GUI **automatically** at the next logon of this (non privileged) user (with highest privileges).
55
56
You need to walk through some small steps to achieve this goal.
57
58
### 2 scripts that help us
59
#### Script 1 create_main_task_only_runonce.cmd
60
```
61
@ECHO OFF
62
CLS
63
64
REM Detect current user (should be an administrator)
65
SET USER=%USERNAME%
66
SET DOM=%USERDOMAIN%
67
SET ACCOUNT=%DOM%\%USER%
68
SET TASKNAME=OpenVPN Logon Task Creator (main)
69
70
REM Where to store the created XML-File
71
SET XML=%temp%\%RANDOM%_temp.xml
72
73
REM What to start via the generated task
74
SET TOSTART=C:\ProgramData\OpenVPN\create_usertask.cmd
75
76
ECHO ^<?xml version="1.0" encoding="UTF-16"?^> > "%XML%"
77
ECHO ^<Task version="1.3" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"^> >> "%XML%"
78
echo. ^<RegistrationInfo^> >> "%XML%"
79
echo. ^<Date^>2001-01-01T01:01:01.01^</Date^> >> "%XML%"
80
echo. ^<Author^>Der PCFreak^</Author^> >> "%XML%"
81
echo. ^<Description^>This task will be executed at logon of any user. The script will then determine the username and domain/computer of this user. The user will then added to the group "Network Configuration Operators" and additionally a new scheduled task with name "%DOM%_%USER%_openvpn" will be created. The automatically created task will be set up to only run when the specific, detected user logs on. This task will then start OpenVPN-GUI with highest privileges at logon.^</Description^> >> "%XML%"
82
echo. ^</RegistrationInfo^> >> "%XML%"
83
84
echo. ^<Triggers^> >> "%XML%"
85
echo. ^<LogonTrigger^> >> "%XML%"
86
echo. ^<StartBoundary^>2001-01-01T01:01:01^</StartBoundary^> >> "%XML%"
87
echo. ^<Enabled^>true^</Enabled^> >> "%XML%"
88
echo. ^</LogonTrigger^> >> "%XML%"
89
echo. ^</Triggers^> >> "%XML%"
90
91
echo. ^<Principals^> >> "%XML%"
92
echo. ^<Principal id="Author"^> >> "%XML%"
93
echo. ^<UserId^>%ACCOUNT%^</UserId^> >> "%XML%"
94
echo. ^<LogonType^>Password^</LogonType^> >> "%XML%"
95
echo. ^<RunLevel^>HighestAvailable^</RunLevel^> >> "%XML%"
96
echo. ^</Principal^> >> "%XML%"
97
echo. ^</Principals^> >> "%XML%"
98
99
echo. ^<Settings^> >> "%XML%"
100
echo. ^<MultipleInstancesPolicy^>IgnoreNew^</MultipleInstancesPolicy^> >> "%XML%"
101
echo. ^<DisallowStartIfOnBatteries^>false^</DisallowStartIfOnBatteries^> >> "%XML%"
102
echo. ^<StopIfGoingOnBatteries^>false^</StopIfGoingOnBatteries^> >> "%XML%"
103
echo. ^<AllowHardTerminate^>true^</AllowHardTerminate^> >> "%XML%"
104
echo. ^<StartWhenAvailable^>false^</StartWhenAvailable^> >> "%XML%"
105
echo. ^<RunOnlyIfNetworkAvailable^>false^</RunOnlyIfNetworkAvailable^> >> "%XML%"
106
echo. ^<IdleSettings^> >> "%XML%"
107
echo. ^<StopOnIdleEnd^>true^</StopOnIdleEnd^> >> "%XML%"
108
echo. ^<RestartOnIdle^>false^</RestartOnIdle^> >> "%XML%"
109
echo. ^</IdleSettings^> >> "%XML%"
110
echo. ^<AllowStartOnDemand^>true^</AllowStartOnDemand^> >> "%XML%"
111
echo. ^<Enabled^>true^</Enabled^> >> "%XML%"
112
echo. ^<Hidden^>false^</Hidden^> >> "%XML%"
113
echo. ^<RunOnlyIfIdle^>false^</RunOnlyIfIdle^> >> "%XML%"
114
echo. ^<WakeToRun^>false^</WakeToRun^> >> "%XML%"
115
echo. ^<ExecutionTimeLimit^>P3D^</ExecutionTimeLimit^> >> "%XML%"
116
echo. ^<Priority^>7^</Priority^> >> "%XML%"
117
echo. ^</Settings^> >> "%XML%"
118
119
echo. ^<Actions Context="Author"^> >> "%XML%"
120
echo. ^<Exec^> >> "%XML%"
121
echo. ^<Command^>"%TOSTART%"^</Command^> >> "%XML%"
122
echo. ^</Exec^> >> "%XML%"
123
echo. ^</Actions^> >> "%XML%"
124
125
echo ^</Task^> >> "%XML%"
126
127
128
REM Create the task using schtasks
129
REM use /f to make sure we can re-create this task on demand
130
%windir%\system32\schtasks.exe /create /TN "%TASKNAME%" /XML "%XML%" /RU %ACCOUNT% /RP "" /F
131
132
REM Delete temporary XML FILE
133
DEL /Q "%XML%"
134
```
135
Please verify the variable **TOSTART** at the beginning of the script. It must represent the physical location of **create_usertask.cmd** (our second script).
136
137
#### Script 2 create_usertask.cmd
138
```
139
@ECHO OFF
140
CLS
141
142
REM Some Variables
143
144
REM Where to store the created XML-File
145
SET XML=%temp%\%RANDOM%_temp.xml
146
147
REM Name of the Network Configuration Operators group (without quotes)
148
SET NGROUP=Network Configuration Operators
149
150
REM What to start via the generated task
151
SET TOSTART=C:\Program Files\OpenVPN\bin\openvpn-gui.exe
152
153
154
REM We need to find the domain/computer and username of the user that is logging on
155
REM We run under a different user context so we need a trick to do that
156
REM Session to search, usually "console"
157
SET SESSION=console
158
REM Process to search, usually "explorer.exe"
159
SET PROCESS=explorer.exe
160
for /f "usebackq tokens=8,9 delims=\ " %%a IN (`tasklist /fi "SESSIONNAME eq %SESSION%" /FI "IMAGENAME eq %PROCESS%" /V /NH`) do (
161
SET DOM=%%a
162
SET USER=%%b
163
SET ACCOUNT=%%a\%%b
164
)
165
echo The detected user was %USER% in domain/computer %DOM% .
166
167
168
169
ECHO ^<?xml version="1.0" encoding="UTF-16"?^> > "%XML%"
170
171
ECHO. ^<Task version="1.3" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"^> >> "%XML%"
172
173
ECHO. ^<Settings^> >> "%XML%"
174
ECHO. ^<MultipleInstancesPolicy^>StopExisting^</MultipleInstancesPolicy^> >> "%XML%"
175
ECHO. ^<DisallowStartIfOnBatteries^>false^</DisallowStartIfOnBatteries^> >> "%XML%"
176
ECHO. ^<StopIfGoingOnBatteries^>false^</StopIfGoingOnBatteries^> >> "%XML%"
177
ECHO. ^<AllowHardTerminate^>true^</AllowHardTerminate^> >> "%XML%"
178
ECHO. ^<StartWhenAvailable^>false^</StartWhenAvailable^> >> "%XML%"
179
ECHO. ^<RunOnlyIfNetworkAvailable^>false^</RunOnlyIfNetworkAvailable^> >> "%XML%"
180
ECHO. ^<IdleSettings^> >> "%XML%"
181
ECHO. ^<StopOnIdleEnd^>true^</StopOnIdleEnd^> >> "%XML%"
182
ECHO. ^<RestartOnIdle^>false^</RestartOnIdle^> >> "%XML%"
183
ECHO. ^</IdleSettings^> >> "%XML%"
184
ECHO. ^<AllowStartOnDemand^>true^</AllowStartOnDemand^> >> "%XML%"
185
ECHO. ^<Enabled^>true^</Enabled^> >> "%XML%"
186
ECHO. ^<Hidden^>false^</Hidden^> >> "%XML%"
187
ECHO. ^<RunOnlyIfIdle^>false^</RunOnlyIfIdle^> >> "%XML%"
188
ECHO. ^<DisallowStartOnRemoteAppSession^>false^</DisallowStartOnRemoteAppSession^> >> "%XML%"
189
ECHO. ^<UseUnifiedSchedulingEngine^>false^</UseUnifiedSchedulingEngine^> >> "%XML%"
190
ECHO. ^<WakeToRun^>false^</WakeToRun^> >> "%XML%"
191
ECHO. ^<ExecutionTimeLimit^>PT0S^</ExecutionTimeLimit^> >> "%XML%"
192
ECHO. ^<Priority^>7^</Priority^> >> "%XML%"
193
ECHO. ^</Settings^> >> "%XML%"
194
195
ECHO. ^<Actions Context="Author"^> >> "%XML%"
196
ECHO. ^<Exec^> >> "%XML%"
197
ECHO. ^<Command^>"%TOSTART%"^</Command^> >> "%XML%"
198
ECHO. ^</Exec^> >> "%XML%"
199
ECHO. ^</Actions^> >> "%XML%"
200
201
ECHO. ^<RegistrationInfo^> >> "%XML%"
202
ECHO. ^<Date^>2013-07-11T11:39:44.2138665^</Date^> >> "%XML%"
203
ECHO. ^<Author^>Der PCFreak^</Author^> >> "%XML%"
204
echo. ^<Description^>This task will run when the user %ACCOUNT% logs on. It will then start OpenVPN-GUI with in the context of this user with highest privileges at logon of this user.^</Description^> >> "%XML%"
205
ECHO. ^</RegistrationInfo^> >> "%XML%"
206
207
ECHO. ^<Principals^> >> "%XML%"
208
ECHO. ^<Principal id="Author"^> >> "%XML%"
209
ECHO. ^<UserId^>%ACCOUNT%^</UserId^> >> "%XML%"
210
ECHO. ^<LogonType^>InteractiveToken^</LogonType^> >> "%XML%"
211
ECHO. ^<RunLevel^>HighestAvailable^</RunLevel^> >> "%XML%"
212
ECHO. ^</Principal^> >> "%XML%"
213
ECHO. ^</Principals^> >> "%XML%"
214
215
ECHO. ^<Triggers^> >> "%XML%"
216
ECHO. ^<LogonTrigger^> >> "%XML%"
217
ECHO. ^<Enabled^>true^</Enabled^> >> "%XML%"
218
ECHO. ^<UserId^>%ACCOUNT%^</UserId^> >> "%XML%"
219
ECHO. ^</LogonTrigger^> >> "%XML%"
220
ECHO. ^</Triggers^> >> "%XML%"
221
222
ECHO. ^</Task^> >> "%XML%"
223
224
225
REM Create the task using schtasks
226
REM do not use /f since we only want to create this task once!
227
%windir%\system32\schtasks.exe /create /xml "%XML%" /tn "%DOM%_%USER%_openvpn" /DELAY 0000:25
228
229
230
REM Add the user to the Network Configuration Operators group
231
net localgroup "%NGROUP%" %ACCOUNT% /add
232
233
REM Delete temporary XML FILE
234
DEL /Q "%XML%"
235
```
236
237
Take a look at the beginning of the script and change the variables **NGROUP** and **TOSTART** to your localized version of the **Network Configuration Operators** group and your location of **openvpn-gui.exe**.
238
239
### Install OpenVPN-GUI
240
Do a default installation of OpenVPN-GUI and also copy the necessary connection profiles to the target machine. ** Do this as administrative user. **
241
242
### Prepare and fix Registry Keys
243
Start OpenVPN-GUI once as an administrative user. This will create the following registry key:
244
245
```
246
HKEY_LOCAL_MACHINE\SOFTWARE\OpenVPN-GUI
247
```
248
249
Close OpenVPN-GUI. Open the registry editor (regedit.exe) and take a look at this registry key:
250
251
```
252
HKEY_LOCAL_MACHINE\SOFTWARE\OpenVPN-GUI\log_dir
253
```
254
255
By default it points to
256
257
```
258
C:\Program Files\OpenVPN\log
259
```
260
This folder is not writeable by nonprivileged users, so they will get error messages when connecting.
261
262
Just change it to
263
264
```
265
%temp%\OpenVPN\log
266
```
267
268
With this change, a nonprivileged user logs to his personal temp folder, e.g.
269
270
```
271
C:\Users\user1\AppData\Local\Temp\OpenVPN\log
272
```
273
### Copy script files to target
274
Create the folder
275
276
```
277
C:\Programdata\OpenVPN
278
```
279
and copy the above 2 script files
280
281
```
282
create_usertask.cmd
283
create_main_task_only_runonce.cmd
284
```
285
286
to this directory. ** Please double-check and make sure, that this files cannot be changed by non-privileged users! **
287
288
289
290
### Setup the main task
291
Use explorer.exe and jump to the directory where you stored the 2 scripts from above, usually
292
```
293
C:\ProgramData\OpenVPN
294
```
295
Right-click **create_main_task_only_runonce.cmd** and select **Run as administrator**. A command prompt will open and ask you for the password of the administrative account. Enter it correctly.
296
297
![https://dl.dropboxusercontent.com/u/682899/_do_not_delete_/pictures%20for%20openvpn%20wiki%20openvpn.net/001-openvpn.png](./https://dl.dropboxusercontent.com/u/682899/_do_not_delete_/pictures%20for%20openvpn%20wiki%20openvpn.net/001-openvpn.png)
298
299
If everything went right, you have now a new scheduled task in the **Task Scheduler Library** with the name
300
301
```
302
OpenVPN Logon Task Creator (main)
303
```
304
305
![https://dl.dropboxusercontent.com/u/682899/_do_not_delete_/pictures%20for%20openvpn%20wiki%20openvpn.net/002-openvpn.png](./https://dl.dropboxusercontent.com/u/682899/_do_not_delete_/pictures%20for%20openvpn%20wiki%20openvpn.net/002-openvpn.png)
306
307
It is setup to run
308
309
```
310
with the administrators account
311
with highest privileges
312
at logon of any user
313
executing C:\Programdata\OpenVPN\create_usertask.cmd
314
```
315
316
**Verify the automated generation of this task**.
317
318
319
### Change OpenVPN-GUI shortcut
320
We now change the shortcut(s) that start OpenVPN to a different target.They are usually located here:
321
322
```
323
C:\Users\Public\Desktop\OpenVPN GUI.lnk
324
C:\Users\All Users\Microsoft\Windows\Start Menu\Programs\OpenVPN\OpenVPN GUI.lnk
325
```
326
327
Change all shortcuts to the following settings (via properties).
328
329
```
330
Target: %windir%\System32\schtasks.exe /RUN /TN "%USERDOMAIN%_%USERNAME%_openvpn"
331
Icon : C:\Program Files\OpenVPN\icon.ico (or any other icon you like)
332
```
333
![https://dl.dropboxusercontent.com/u/682899/_do_not_delete_/pictures%20for%20openvpn%20wiki%20openvpn.net/003-openvpn.png](./https://dl.dropboxusercontent.com/u/682899/_do_not_delete_/pictures%20for%20openvpn%20wiki%20openvpn.net/003-openvpn.png)
334
335
The rest of the settings can be left to their defaults.
336
337
338
## Test it!
339
Logon as a nonprivileged user, let's assume, the username is **user1** and he is logging on to machine **win7x64-vm**. The following will happen.
340
341
### First logon
342
#### Main scheduled task will execute
343
The "main" scheduled task **OpenVPN Logon Task Creator (main)** will run. It will programmatically
344
345
```
346
add user1 to the localgroup "Network Configuration Operators"
347
create a userspecific scheduled task with the name win7x64_user1_openvpn
348
```
349
350
![https://dl.dropboxusercontent.com/u/682899/_do_not_delete_/pictures%20for%20openvpn%20wiki%20openvpn.net/004-openvpn.png](./https://dl.dropboxusercontent.com/u/682899/_do_not_delete_/pictures%20for%20openvpn%20wiki%20openvpn.net/004-openvpn.png)
351
352
Since we changed the target for the OpenVPN-GUI shortcuts, the user can now already click the OpenVPN-GUI desktop icon, which will then run the scheduled task **win7x64_user1_openvpn** on demand. **win7x64_user1_openvpn** will then execute **openvpn-gui.exe** in the users context but with **highest privileges**.
353
354
### Security related information
355
There are 2 registry keys, that are dangerous and can allow the user to open an administrative prompt on the machine. They are
356
357
```
358
HKEY_LOCAL_MACHINE\SOFTWARE\OpenVPN-GUI\editor
359
and
360
HKEY_LOCAL_MACHINE\SOFTWARE\OpenVPN-GUI\log_viewer
361
```
362
363
When using my method and click on ** View Log ** or ** Edit config **, by default notepad.exe will open (and of course) with highest privileges. To fix this, you should change the registry to an executable (you created), that shows an error message. I did this with a small AutoIT-Script, that does exactly that. I called it
364
365
```
366
notallowed.exe
367
```
368
The source is added to this Wiki page as
369
370
```
371
notallowed.au3
372
```
373
374
** Without this change your installation is vulnerable and normal users can get an elevated command prompt, so absolutely change this registry keys!!!! **
375
376
So I additionally changed the registry for OpenVPN-GUI to
377
378
```
379
Key : HKEY_LOCAL_MACHINE\SOFTWARE\OpenVPN-GUI
380
Name : editor
381
Value: C:\ProgramData\OpenVPN\notallowed.exe
382
383
Key : HKEY_LOCAL_MACHINE\SOFTWARE\OpenVPN-GUI
384
Name : log_viewer
385
Value: C:\ProgramData\OpenVPN\notallowed.exe
386
```
387
388
Here is a screenshot:
389
390
![https://dl.dropboxusercontent.com/u/682899/_do_not_delete_/pictures%20for%20openvpn%20wiki%20openvpn.net/005-openvpn.png](./https://dl.dropboxusercontent.com/u/682899/_do_not_delete_/pictures%20for%20openvpn%20wiki%20openvpn.net/005-openvpn.png)
391
392
When notallowed.exe is executed it just shows this message:
393
394
![https://dl.dropboxusercontent.com/u/682899/_do_not_delete_/pictures%20for%20openvpn%20wiki%20openvpn.net/006-openvpn.png](./https://dl.dropboxusercontent.com/u/682899/_do_not_delete_/pictures%20for%20openvpn%20wiki%20openvpn.net/006-openvpn.png)
395
396
### Future logons
397
#### Main scheduled task will execute
398
Since the **main** task has already run previously, it will **NOT** recreate the users personal scheduled task. - It does nothing.
399
400
#### User task will execute
401
Since the **user** task **win7x64_user1_openvpn** was present at logon, it get's executed and starts **openvpn-gui.exe**. So after the user logged in, he/she has the OpenVPN-GUI running in the system tray and is ready to establish connections **without administrative privileges**
402
403
## Summary
404
My personal opinion is, that this is a nice workaround for the **nonprivileged user problem**. It can easily be deployed, it is **Open Source** and you can change it to your needs. If you use, change or blog it, please keep a line in your code, that refers to me (Der PCFreak) and my Blog ([http://blog.pcfreak.de]).
405
406
If I have time, I will add some screenshots and I am planning to create a video on Youtube, that shows exactly how it works.
407
408
Since this was the first time I posted to this Wiki, I hope I made no mistakes and no errors.
409
410
Thank you for reading!