Q: how to restrict access selectively to client initiated local port forward
Michael O'Cleirigh
mocleiri at jpint.utoronto.ca
Sat Sep 29 00:36:32 EST 2007
Hello,
First, thanks for all the feedback to my question.
>> Then you should run OpenVPN over TCP on port 22 or whatever you're
>> using for SSH that can be reached from clients, on another public IP
>> address and be done.
>>
>
> This is likely the correct solution.
>
I hadn't done this because the OpenVPN Documentation recommends not
tunneling TCP/IP through TCP/IP but I see know that thats exactly what
ssh is doing anyways.
>>> However as far as I can tell there is no way in OpenSSH to define
>>> an access control policy for which connecting users are allowed to
>>> redirect through which local IP.
>>>
>> Right, because there's no way for OpenSSH to implement it anyway.
>>
>
> You are right in that it can't be done in the base OpenSSH code.
> However, I know it can be done with patches to OpenSSH because we
> actually implemented it. We even had it so that one user wouldn't be
> able bogart well known ports. So it can be done. Its just not easy and
> probably not worth the hassle in this instance.
I finally figured out how to modify the OpenSSH source to hook in my
module. Here are some of the details for the benefit of the people
searching the list archives in the future:
Our module reads a custom passwd file that contains:
1. username
2. password
3. list of common names they are allowed to connect to (in our setup all
common names have a client configuration directory file; the module will
parse this file to extract the IP that is allowed to accessed by that
common_name).
We have an OpenVPN authentication plugin and a PAM module that also use
the same core module authenticating our users for this proxy.
For OpenSSH the modification is to change how the
channels.c:channel_connect_to(...) method works from checking the
permitted_open array which is setup at startup to checking my
configuration files which are changeable at runtime.
We modify channels.c:channel_connect_to() as follows:
1. Add a new parameter of type Authctxt* which is passed in from the
serverloop.c as the_authctxt and NULL everywhere else. This holds the
username which is what we need for testing the allowability of a given
(username, host) tcp forward.
2. The comment 'channel_connect_to' was: /* XXX check permission */
which turned out to indicate the insertion point for my method:
_is_tcp_forward_allowed ().
3. Change the names of a few structures in sshconnect2.c which overlap
with Authctxt, Authmethod as defined in auth.h (vim global replace is
all that is required). This is because channels.h needs to be modified
for the channel_connect_to prototype and is used in a wider context.
4. The new method works like:
/* Check if connecting to that port is permitted and connect. */
int
channel_connect_to(const char *host, u_short port, Authctxt *authctxt)
{
error ("channel_connect_to: host=%s, port = %d\n", host, port);
if (authctxt != NULL) {
if (_is_tcp_forward_allowed ("/etc/proxy_passwd",
"/etc/openvpn/ccd", authctxt->user, host) == 0) {
logit("Proxy Extension: Port forwarding NOT permitted
(user=%s, host=%s).", authctxt->user, host);
return -1;
}
else {
/* fall through to initiate the request */
logit("Proxy Extension: Port forwarding IS permitted
(user=%s, host=%s).", authctxt->user, host);
}
}
return connect_to(host, port);
}
Thanks again,
Mike
More information about the openssh-unix-dev
mailing list