OpenVPN as non privileged user
The entire process that is described here be watched at youtube here. 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:
---------------------------------------- | Operating System | ADM | NCO | RHP | ---------------------------------------- | Windows XP | X | | | ---------------------------------------- | Windows XP | | X | | ---------------------------------------- | Windows 7 | X | | | ---------------------------------------- | Windows 7 | | X | X | ---------------------------------------- | Windows 8 | X | | | ---------------------------------------- | Windows 8 | | X | X | ----------------------------------------
RHP = run with highest privileges but in context of a non-administrative user ADM = Member of group "Administrators" NCO = Member of group "Network Configuration Operators"
Note: Since Windows 7 being only a member of the "Network Configuration Operators" group is not enough to be able to set routes.
There are some OpenVPN-Clients that are able to establish connections and setting routes without administrative privileges but they are either unstable SecurePoint SSL VPN) or do not have all necessary features (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.
Solution for Windows XP
Add the non privileged user (e.g. bob) to the group
Network Configuration Operators
You can do this with the following command
net localgroup "Network Configuration Operators" bob /add
and OpenVPN-GUI will perfectly work without administrative privileges.
This solution does no longer work with Windows 7 and above.
New and working solution for Windows 7 (and above)
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).
You need to walk through some small steps to achieve this goal.
2 scripts that help us
Script 1 create_main_task_only_runonce.cmd
@ECHO OFF CLS REM Detect current user (should be an administrator) SET USER=%USERNAME% SET DOM=%USERDOMAIN% SET ACCOUNT=%DOM%\%USER% SET TASKNAME=OpenVPN Logon Task Creator (main) REM Where to store the created XML-File SET XML=%temp%\%RANDOM%_temp.xml REM What to start via the generated task SET TOSTART=C:\ProgramData\OpenVPN\create_usertask.cmd ECHO ^<?xml version="1.0" encoding="UTF-16"?^> > "%XML%" ECHO ^<Task version="1.3" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"^> >> "%XML%" echo. ^<RegistrationInfo^> >> "%XML%" echo. ^<Date^>2001-01-01T01:01:01.01^</Date^> >> "%XML%" echo. ^<Author^>Der PCFreak^</Author^> >> "%XML%" 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%" echo. ^</RegistrationInfo^> >> "%XML%" echo. ^<Triggers^> >> "%XML%" echo. ^<LogonTrigger^> >> "%XML%" echo. ^<StartBoundary^>2001-01-01T01:01:01^</StartBoundary^> >> "%XML%" echo. ^<Enabled^>true^</Enabled^> >> "%XML%" echo. ^</LogonTrigger^> >> "%XML%" echo. ^</Triggers^> >> "%XML%" echo. ^<Principals^> >> "%XML%" echo. ^<Principal id="Author"^> >> "%XML%" echo. ^<UserId^>%ACCOUNT%^</UserId^> >> "%XML%" echo. ^<LogonType^>Password^</LogonType^> >> "%XML%" echo. ^<RunLevel^>HighestAvailable^</RunLevel^> >> "%XML%" echo. ^</Principal^> >> "%XML%" echo. ^</Principals^> >> "%XML%" echo. ^<Settings^> >> "%XML%" echo. ^<MultipleInstancesPolicy^>IgnoreNew^</MultipleInstancesPolicy^> >> "%XML%" echo. ^<DisallowStartIfOnBatteries^>false^</DisallowStartIfOnBatteries^> >> "%XML%" echo. ^<StopIfGoingOnBatteries^>false^</StopIfGoingOnBatteries^> >> "%XML%" echo. ^<AllowHardTerminate^>true^</AllowHardTerminate^> >> "%XML%" echo. ^<StartWhenAvailable^>false^</StartWhenAvailable^> >> "%XML%" echo. ^<RunOnlyIfNetworkAvailable^>false^</RunOnlyIfNetworkAvailable^> >> "%XML%" echo. ^<IdleSettings^> >> "%XML%" echo. ^<StopOnIdleEnd^>true^</StopOnIdleEnd^> >> "%XML%" echo. ^<RestartOnIdle^>false^</RestartOnIdle^> >> "%XML%" echo. ^</IdleSettings^> >> "%XML%" echo. ^<AllowStartOnDemand^>true^</AllowStartOnDemand^> >> "%XML%" echo. ^<Enabled^>true^</Enabled^> >> "%XML%" echo. ^<Hidden^>false^</Hidden^> >> "%XML%" echo. ^<RunOnlyIfIdle^>false^</RunOnlyIfIdle^> >> "%XML%" echo. ^<WakeToRun^>false^</WakeToRun^> >> "%XML%" echo. ^<ExecutionTimeLimit^>P3D^</ExecutionTimeLimit^> >> "%XML%" echo. ^<Priority^>7^</Priority^> >> "%XML%" echo. ^</Settings^> >> "%XML%" echo. ^<Actions Context="Author"^> >> "%XML%" echo. ^<Exec^> >> "%XML%" echo. ^<Command^>"%TOSTART%"^</Command^> >> "%XML%" echo. ^</Exec^> >> "%XML%" echo. ^</Actions^> >> "%XML%" echo ^</Task^> >> "%XML%" REM Create the task using schtasks REM use /f to make sure we can re-create this task on demand %windir%\system32\schtasks.exe /create /TN "%TASKNAME%" /XML "%XML%" /RU %ACCOUNT% /RP "" /F REM Delete temporary XML FILE DEL /Q "%XML%"
Please verify the variable TOSTART at the beginning of the script. It must represent the physical location of create_usertask.cmd (our second script).
Script 2 create_usertask.cmd
@ECHO OFF CLS REM Some Variables REM Where to store the created XML-File SET XML=%temp%\%RANDOM%_temp.xml REM Name of the Network Configuration Operators group (without quotes) SET NGROUP=Network Configuration Operators REM What to start via the generated task SET TOSTART=C:\Program Files\OpenVPN\bin\openvpn-gui.exe REM We need to find the domain/computer and username of the user that is logging on REM We run under a different user context so we need a trick to do that REM Session to search, usually "console" SET SESSION=console REM Process to search, usually "explorer.exe" SET PROCESS=explorer.exe for /f "usebackq tokens=8,9 delims=\ " %%a IN (`tasklist /fi "SESSIONNAME eq %SESSION%" /FI "IMAGENAME eq %PROCESS%" /V /NH`) do ( SET DOM=%%a SET USER=%%b SET ACCOUNT=%%a\%%b ) echo The detected user was %USER% in domain/computer %DOM% . ECHO ^<?xml version="1.0" encoding="UTF-16"?^> > "%XML%" ECHO. ^<Task version="1.3" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"^> >> "%XML%" ECHO. ^<Settings^> >> "%XML%" ECHO. ^<MultipleInstancesPolicy^>StopExisting^</MultipleInstancesPolicy^> >> "%XML%" ECHO. ^<DisallowStartIfOnBatteries^>false^</DisallowStartIfOnBatteries^> >> "%XML%" ECHO. ^<StopIfGoingOnBatteries^>false^</StopIfGoingOnBatteries^> >> "%XML%" ECHO. ^<AllowHardTerminate^>true^</AllowHardTerminate^> >> "%XML%" ECHO. ^<StartWhenAvailable^>false^</StartWhenAvailable^> >> "%XML%" ECHO. ^<RunOnlyIfNetworkAvailable^>false^</RunOnlyIfNetworkAvailable^> >> "%XML%" ECHO. ^<IdleSettings^> >> "%XML%" ECHO. ^<StopOnIdleEnd^>true^</StopOnIdleEnd^> >> "%XML%" ECHO. ^<RestartOnIdle^>false^</RestartOnIdle^> >> "%XML%" ECHO. ^</IdleSettings^> >> "%XML%" ECHO. ^<AllowStartOnDemand^>true^</AllowStartOnDemand^> >> "%XML%" ECHO. ^<Enabled^>true^</Enabled^> >> "%XML%" ECHO. ^<Hidden^>false^</Hidden^> >> "%XML%" ECHO. ^<RunOnlyIfIdle^>false^</RunOnlyIfIdle^> >> "%XML%" ECHO. ^<DisallowStartOnRemoteAppSession^>false^</DisallowStartOnRemoteAppSession^> >> "%XML%" ECHO. ^<UseUnifiedSchedulingEngine^>false^</UseUnifiedSchedulingEngine^> >> "%XML%" ECHO. ^<WakeToRun^>false^</WakeToRun^> >> "%XML%" ECHO. ^<ExecutionTimeLimit^>PT0S^</ExecutionTimeLimit^> >> "%XML%" ECHO. ^<Priority^>7^</Priority^> >> "%XML%" ECHO. ^</Settings^> >> "%XML%" ECHO. ^<Actions Context="Author"^> >> "%XML%" ECHO. ^<Exec^> >> "%XML%" ECHO. ^<Command^>"%TOSTART%"^</Command^> >> "%XML%" ECHO. ^</Exec^> >> "%XML%" ECHO. ^</Actions^> >> "%XML%" ECHO. ^<RegistrationInfo^> >> "%XML%" ECHO. ^<Date^>2013-07-11T11:39:44.2138665^</Date^> >> "%XML%" ECHO. ^<Author^>Der PCFreak^</Author^> >> "%XML%" 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%" ECHO. ^</RegistrationInfo^> >> "%XML%" ECHO. ^<Principals^> >> "%XML%" ECHO. ^<Principal id="Author"^> >> "%XML%" ECHO. ^<UserId^>%ACCOUNT%^</UserId^> >> "%XML%" ECHO. ^<LogonType^>InteractiveToken^</LogonType^> >> "%XML%" ECHO. ^<RunLevel^>HighestAvailable^</RunLevel^> >> "%XML%" ECHO. ^</Principal^> >> "%XML%" ECHO. ^</Principals^> >> "%XML%" ECHO. ^<Triggers^> >> "%XML%" ECHO. ^<LogonTrigger^> >> "%XML%" ECHO. ^<Enabled^>true^</Enabled^> >> "%XML%" ECHO. ^<UserId^>%ACCOUNT%^</UserId^> >> "%XML%" ECHO. ^</LogonTrigger^> >> "%XML%" ECHO. ^</Triggers^> >> "%XML%" ECHO. ^</Task^> >> "%XML%" REM Create the task using schtasks REM do not use /f since we only want to create this task once! %windir%\system32\schtasks.exe /create /xml "%XML%" /tn "%DOM%_%USER%_openvpn" /DELAY 0000:25 REM Add the user to the Network Configuration Operators group net localgroup "%NGROUP%" %ACCOUNT% /add REM Delete temporary XML FILE DEL /Q "%XML%"
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.
Install OpenVPN-GUI
Do a default installation of OpenVPN-GUI and also copy the necessary connection profiles to the target machine. Do this as administrative user.
Prepare and fix Registry Keys
Start OpenVPN-GUI once as an administrative user. This will create the following registry key:
HKEY_LOCAL_MACHINE\SOFTWARE\OpenVPN-GUI
Close OpenVPN-GUI. Open the registry editor (regedit.exe) and take a look at this registry key:
HKEY_LOCAL_MACHINE\SOFTWARE\OpenVPN-GUI\log_dir
By default it points to
C:\Program Files\OpenVPN\log
This folder is not writeable by nonprivileged users, so they will get error messages when connecting.
Just change it to
%temp%\OpenVPN\log
With this change, a nonprivileged user logs to his personal temp folder, e.g.
C:\Users\user1\AppData\Local\Temp\OpenVPN\log
Copy script files to target
Create the folder
C:\Programdata\OpenVPN
and copy the above 2 script files
create_usertask.cmd create_main_task_only_runonce.cmd
to this directory. Please double-check and make sure, that this files cannot be changed by non-privileged users!
Setup the main task
Use explorer.exe and jump to the directory where you stored the 2 scripts from above, usually
C:\ProgramData\OpenVPN
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.
If everything went right, you have now a new scheduled task in the Task Scheduler Library with the name
OpenVPN Logon Task Creator (main)
It is setup to run
with the administrators account with highest privileges at logon of any user executing C:\Programdata\OpenVPN\create_usertask.cmd
Verify the automated generation of this task.
Change OpenVPN-GUI shortcut
We now change the shortcut(s) that start OpenVPN to a different target.They are usually located here:
C:\Users\Public\Desktop\OpenVPN GUI.lnk C:\Users\All Users\Microsoft\Windows\Start Menu\Programs\OpenVPN\OpenVPN GUI.lnk
Change all shortcuts to the following settings (via properties).
Target: %windir%\System32\schtasks.exe /RUN /TN "%USERDOMAIN%_%USERNAME%_openvpn" Icon : C:\Program Files\OpenVPN\icon.ico (or any other icon you like)
The rest of the settings can be left to their defaults.
Test it!
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.
First logon
Main scheduled task will execute
The "main" scheduled task OpenVPN Logon Task Creator (main) will run. It will programmatically
add user1 to the localgroup "Network Configuration Operators" create a userspecific scheduled task with the name win7x64_user1_openvpn
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.
Security related information
There are 2 registry keys, that are dangerous and can allow the user to open an administrative prompt on the machine. They are
HKEY_LOCAL_MACHINE\SOFTWARE\OpenVPN-GUI\editor and HKEY_LOCAL_MACHINE\SOFTWARE\OpenVPN-GUI\log_viewer
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
notallowed.exe
The source is added to this Wiki page as
notallowed.au3
Without this change your installation is vulnerable and normal users can get an elevated command prompt, so absolutely change this registry keys!!!!
So I additionally changed the registry for OpenVPN-GUI to
Key : HKEY_LOCAL_MACHINE\SOFTWARE\OpenVPN-GUI Name : editor Value: C:\ProgramData\OpenVPN\notallowed.exe Key : HKEY_LOCAL_MACHINE\SOFTWARE\OpenVPN-GUI Name : log_viewer Value: C:\ProgramData\OpenVPN\notallowed.exe
Here is a screenshot:
When notallowed.exe is executed it just shows this message:
Future logons
Main scheduled task will execute
Since the main task has already run previously, it will NOT recreate the users personal scheduled task. - It does nothing.
User task will execute
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
Summary
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).
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.
Since this was the first time I posted to this Wiki, I hope I made no mistakes and no errors.
Thank you for reading!
Attachments (3)
-
create_main_task_only_runonce.cmd (3.4 KB) - added by 11 years ago.
create_main_task_only_runonce.cmd
-
create_usertask.cmd (3.9 KB) - added by 11 years ago.
create_usertask.cmd
-
notallowed.au3 (1017 bytes) - added by 11 years ago.
notallowed.au3 (needed for security)
Download all attachments as: .zip