mirror of
https://github.com/OpenVPN/openvpn.git
synced 2025-05-09 13:41:06 +08:00
Allow OpenVPN to run completely unprivileged under Linux
by allowing openvpn --mktun to be used with --user and --group to set the UID/GID of the tun device node. Also added --iproute option to allow an alternative command to be executed in place of the default iproute2 command (Alon Bar-Lev). git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@2639 e7ae566f-a301-0410-adde-c780ea21d3b5
This commit is contained in:
parent
7686b1c407
commit
0aee9ca7e7
2
init.c
2
init.c
@ -426,7 +426,7 @@ do_persist_tuntap (const struct options *options)
|
||||
"options --mktun or --rmtun should only be used together with --dev");
|
||||
tuncfg (options->dev, options->dev_type, options->dev_node,
|
||||
options->tun_ipv6, options->persist_mode,
|
||||
&options->tuntap_options);
|
||||
options->username, options->groupname, &options->tuntap_options);
|
||||
if (options->persist_mode && options->lladdr)
|
||||
set_lladdr(options->dev, options->lladdr, NULL);
|
||||
return true;
|
||||
|
4
lladdr.c
4
lladdr.c
@ -24,8 +24,8 @@ int set_lladdr(const char *ifname, const char *lladdr,
|
||||
#if defined(TARGET_LINUX)
|
||||
#ifdef CONFIG_FEATURE_IPROUTE
|
||||
openvpn_snprintf (cmd, sizeof (cmd),
|
||||
IPROUTE_PATH " link set addr %s dev %s",
|
||||
lladdr, ifname);
|
||||
"%s link set addr %s dev %s",
|
||||
iproute_path, lladdr, ifname);
|
||||
#else
|
||||
openvpn_snprintf (cmd, sizeof (cmd),
|
||||
IFCONFIG_PATH " %s hw ether %s",
|
||||
|
4
misc.c
4
misc.c
@ -44,6 +44,10 @@
|
||||
|
||||
#include "memdbg.h"
|
||||
|
||||
#ifdef CONFIG_FEATURE_IPROUTE
|
||||
const char *iproute_path = IPROUTE_PATH;
|
||||
#endif
|
||||
|
||||
/* Redefine the top level directory of the filesystem
|
||||
to restrict access to files for security */
|
||||
void
|
||||
|
7
misc.h
7
misc.h
@ -269,4 +269,11 @@ void configure_path (void);
|
||||
void get_user_pass_auto_userid (struct user_pass *up, const char *tag);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* /sbin/ip path, may be overridden
|
||||
*/
|
||||
#ifdef CONFIG_FEATURE_IPROUTE
|
||||
extern const char *iproute_path;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
16
openvpn.8
16
openvpn.8
@ -71,6 +71,8 @@ openvpn \- secure IP tunnel daemon.
|
||||
[\ \fB\-\-dev\-type\fR\ \fIdevice\-type\fR\ ]
|
||||
[\ \fB\-\-dev\-node\fR\ \fInode\fR\ ]
|
||||
[\ \fB\-\-lladdr\fR\ \fIaddress\fR\ ]
|
||||
[\ \fB\-\-user\fR\ \fIuser\fR\ ]
|
||||
[\ \fB\-\-group\fR\ \fIgroup\fR\ ]
|
||||
.in -4
|
||||
.ti +4
|
||||
.hy
|
||||
@ -164,6 +166,7 @@ openvpn \- secure IP tunnel daemon.
|
||||
[\ \fB\-\-inetd\fR\ \fI[wait|nowait]\ [progname]\fR\ ]
|
||||
[\ \fB\-\-ip\-win32\fR\ \fImethod\fR\ ]
|
||||
[\ \fB\-\-ipchange\fR\ \fIcmd\fR\ ]
|
||||
[\ \fB\-\-iproute\fR\ \fIcmd\fR\ ]
|
||||
[\ \fB\-\-iroute\fR\ \fInetwork\ [netmask]\fR\ ]
|
||||
[\ \fB\-\-keepalive\fR\ \fIn\ m\fR\ ]
|
||||
[\ \fB\-\-key\-method\fR\ \fIm\fR\ ]
|
||||
@ -923,6 +926,11 @@ Specify the link layer address, more commonly known as the MAC address.
|
||||
Only applied to TAP devices.
|
||||
.\"*********************************************************
|
||||
.TP
|
||||
.B --iproute cmd
|
||||
Set alternate command to execute instead of default iproute2 command.
|
||||
May be used in order to execute OpenVPN in unprivileged environment.
|
||||
.\"*********************************************************
|
||||
.TP
|
||||
.B --ifconfig l rn
|
||||
Set TUN/TAP adapter parameters.
|
||||
.B l
|
||||
@ -4306,6 +4314,14 @@ Remove a persistent tunnel.
|
||||
.B --dev tunX | tapX
|
||||
TUN/TAP device
|
||||
.\"*********************************************************
|
||||
.TP
|
||||
.B --user user
|
||||
Optional user to be owner of this tunnel.
|
||||
.\"*********************************************************
|
||||
.TP
|
||||
.B --group group
|
||||
Optional group to be owner of this tunnel.
|
||||
.\"*********************************************************
|
||||
.SS Windows-Specific Options:
|
||||
.\"*********************************************************
|
||||
.TP
|
||||
|
12
options.c
12
options.c
@ -156,6 +156,9 @@ static const char usage_message[] =
|
||||
"--lladdr hw : Set the link layer address of the tap device.\n"
|
||||
"--topology t : Set --dev tun topology: 'net30', 'p2p', or 'subnet'.\n"
|
||||
"--tun-ipv6 : Build tun link capable of forwarding IPv6 traffic.\n"
|
||||
#ifdef CONFIG_FEATURE_IPROUTE
|
||||
"--iproute cmd : Use this command instead of default " IPROUTE_PATH ".\n"
|
||||
#endif
|
||||
"--ifconfig l rn : TUN: configure device to use IP address l as a local\n"
|
||||
" endpoint and rn as a remote endpoint. l & rn should be\n"
|
||||
" swapped on the other peer. l & rn must be private\n"
|
||||
@ -591,6 +594,8 @@ static const char usage_message[] =
|
||||
"--rmtun : Remove a persistent tunnel.\n"
|
||||
"--dev tunX|tapX : tun/tap device\n"
|
||||
"--dev-type dt : Device type. See tunnel options above for details.\n"
|
||||
"--user user : User to set privilege to.\n"
|
||||
"--group group : Group to set privilege to.\n"
|
||||
#endif
|
||||
#ifdef ENABLE_PKCS11
|
||||
"\n"
|
||||
@ -3225,6 +3230,13 @@ add_option (struct options *options,
|
||||
VERIFY_PERMISSION (OPT_P_UP);
|
||||
options->tun_ipv6 = true;
|
||||
}
|
||||
#ifdef CONFIG_FEATURE_IPROUTE
|
||||
else if (streq (p[0], "iproute") && p[1])
|
||||
{
|
||||
VERIFY_PERMISSION (OPT_P_UP);
|
||||
iproute_path = p[1];
|
||||
}
|
||||
#endif
|
||||
else if (streq (p[0], "ifconfig") && p[1] && p[2])
|
||||
{
|
||||
VERIFY_PERMISSION (OPT_P_UP);
|
||||
|
6
route.c
6
route.c
@ -777,7 +777,8 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s
|
||||
|
||||
#if defined(TARGET_LINUX)
|
||||
#ifdef CONFIG_FEATURE_IPROUTE
|
||||
buf_printf (&buf, IPROUTE_PATH " route add %s/%d via %s",
|
||||
buf_printf (&buf, "%s route add %s/%d via %s",
|
||||
iproute_path,
|
||||
network,
|
||||
count_netmask_bits(netmask),
|
||||
gateway);
|
||||
@ -934,7 +935,8 @@ delete_route (const struct route *r, const struct tuntap *tt, unsigned int flags
|
||||
|
||||
#if defined(TARGET_LINUX)
|
||||
#ifdef CONFIG_FEATURE_IPROUTE
|
||||
buf_printf (&buf, IPROUTE_PATH " route del %s/%d",
|
||||
buf_printf (&buf, "%s route del %s/%d",
|
||||
iproute_path,
|
||||
network,
|
||||
count_netmask_bits(netmask));
|
||||
#else
|
||||
|
56
tun.c
56
tun.c
@ -577,7 +577,8 @@ do_ifconfig (struct tuntap *tt,
|
||||
* Set the MTU for the device
|
||||
*/
|
||||
openvpn_snprintf (command_line, sizeof (command_line),
|
||||
IPROUTE_PATH " link set dev %s up mtu %d",
|
||||
"%s link set dev %s up mtu %d",
|
||||
iproute_path,
|
||||
actual,
|
||||
tun_mtu
|
||||
);
|
||||
@ -590,7 +591,8 @@ do_ifconfig (struct tuntap *tt,
|
||||
* Set the address for the device
|
||||
*/
|
||||
openvpn_snprintf (command_line, sizeof (command_line),
|
||||
IPROUTE_PATH " addr add dev %s local %s peer %s",
|
||||
"%s addr add dev %s local %s peer %s",
|
||||
iproute_path,
|
||||
actual,
|
||||
ifconfig_local,
|
||||
ifconfig_remote_netmask
|
||||
@ -599,7 +601,8 @@ do_ifconfig (struct tuntap *tt,
|
||||
system_check (command_line, es, S_FATAL, "Linux ip addr add failed");
|
||||
} else {
|
||||
openvpn_snprintf (command_line, sizeof (command_line),
|
||||
IPROUTE_PATH " addr add dev %s %s/%d broadcast %s",
|
||||
"%s addr add dev %s %s/%d broadcast %s",
|
||||
iproute_path,
|
||||
actual,
|
||||
ifconfig_local,
|
||||
count_netmask_bits(ifconfig_remote_netmask),
|
||||
@ -1162,8 +1165,20 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6
|
||||
|
||||
#ifdef TUNSETPERSIST
|
||||
|
||||
/*
|
||||
* This can be removed in future
|
||||
* when all systems will use newer
|
||||
* linux-headers
|
||||
*/
|
||||
#ifndef TUNSETOWNER
|
||||
#define TUNSETOWNER _IOW('T', 204, int)
|
||||
#endif
|
||||
#ifndef TUNSETGROUP
|
||||
#define TUNSETGROUP _IOW('T', 206, int)
|
||||
#endif
|
||||
|
||||
void
|
||||
tuncfg (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, int persist_mode, const struct tuntap_options *options)
|
||||
tuncfg (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, int persist_mode, const char *username, const char *groupname, const struct tuntap_options *options)
|
||||
{
|
||||
struct tuntap *tt;
|
||||
|
||||
@ -1174,6 +1189,26 @@ tuncfg (const char *dev, const char *dev_type, const char *dev_node, bool ipv6,
|
||||
open_tun (dev, dev_type, dev_node, ipv6, tt);
|
||||
if (ioctl (tt->fd, TUNSETPERSIST, persist_mode) < 0)
|
||||
msg (M_ERR, "Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
|
||||
if (username != NULL)
|
||||
{
|
||||
struct user_state user_state;
|
||||
|
||||
if (!get_user (username, &user_state))
|
||||
msg (M_ERR, "Cannot get user entry for %s", username);
|
||||
else
|
||||
if (ioctl (tt->fd, TUNSETOWNER, user_state.pw->pw_uid) < 0)
|
||||
msg (M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", username, dev);
|
||||
}
|
||||
if (groupname != NULL)
|
||||
{
|
||||
struct group_state group_state;
|
||||
|
||||
if (!get_group (groupname, &group_state))
|
||||
msg (M_ERR, "Cannot get group entry for %s", groupname);
|
||||
else
|
||||
if (ioctl (tt->fd, TUNSETGROUP, group_state.gr->gr_gid) < 0)
|
||||
msg (M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", groupname, dev);
|
||||
}
|
||||
close_tun (tt);
|
||||
msg (M_INFO, "Persist state set to: %s", (persist_mode ? "ON" : "OFF"));
|
||||
}
|
||||
@ -1185,6 +1220,19 @@ close_tun (struct tuntap *tt)
|
||||
{
|
||||
if (tt)
|
||||
{
|
||||
#ifdef CONFIG_FEATURE_IPROUTE
|
||||
char command_line[256];
|
||||
/*
|
||||
* Flush IP configuration for the device
|
||||
*/
|
||||
openvpn_snprintf (command_line, sizeof (command_line),
|
||||
"%s addr flush dev %s",
|
||||
iproute_path,
|
||||
tt->actual_name
|
||||
);
|
||||
msg (M_INFO, "%s", command_line);
|
||||
system_check (command_line, NULL, S_FATAL, "Linux ip flush failed");
|
||||
#endif
|
||||
close_tun_generic (tt);
|
||||
free (tt);
|
||||
}
|
||||
|
3
tun.h
3
tun.h
@ -204,7 +204,8 @@ int write_tun (struct tuntap* tt, uint8_t *buf, int len);
|
||||
int read_tun (struct tuntap* tt, uint8_t *buf, int len);
|
||||
|
||||
void tuncfg (const char *dev, const char *dev_type, const char *dev_node,
|
||||
bool ipv6, int persist_mode, const struct tuntap_options *options);
|
||||
bool ipv6, int persist_mode, const char *username,
|
||||
const char *groupname, const struct tuntap_options *options);
|
||||
|
||||
const char *guess_tuntap_dev (const char *dev,
|
||||
const char *dev_type,
|
||||
|
Loading…
x
Reference in New Issue
Block a user