Discussion:
Restrict a client port-forward to 1 port
(too old to reply)
Adriana Rodean
2009-08-12 17:36:11 UTC
Permalink
Hi,

Is it possible to restrict a client port-forwarding to one port?
For example i want client X to open only port 1037 on server through
port-forwarding, client Y only port 1038 and so on...
How can this be possible?
I use private/public keys authentication.
Client version is openssh3.8p1, is windows client, and server version
is latest openssh on a linux machine.

Can anyone help please?

Thank you so much,
Adriana
Aarón Mizrachi
2009-08-13 16:10:41 UTC
Permalink
--nextPart7105899.8ZvITc8vyd
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
Post by Adriana Rodean
Hi,
Is it possible to restrict a client port-forwarding to one port?
For example i want client X to open only port 1037 on server through
port-forwarding, client Y only port 1038 and so on...
How can this be possible?
I use private/public keys authentication.
Client version is openssh3.8p1, is windows client, and server version
is latest openssh on a linux machine.
Can anyone help please?
Indeed. With iptables.=20

each instance of ssh are excecuted with the UID determined by the SSH logon:

Log example:

[GWCONN]: IN=3D OUT=3Dwan0 SRC=3D_._._._ DST=3D_._._._ LEN=3D60 TOS=3D0x00=
PREC=3D0x00=20
TTL=3D64 ID=3D9946 DF PROTO=3DTCP SPT=3D46684 DPT=3D80 WINDOW=3D5840 RES=3D=
0x00 SYN URGP=3D0=20
OPT (020405B40402080A2E3B8D980000000001030305) UID=3D500 GID=3D500

if you set some rule like:

iptables -I OUTPUT -o \! lo -m owner --uid-owner 500 -j LOGDROP
iptables -I OUTPUT -m owner --uid-owner 500 -p tcp -m state --state NEW -m =
tcp=20
=2D-dport 80 -j ACCEPT

you will enable only the port 80 for UID 500 (usernames can be used also).

but remember the -o \! lo, that means that iptables won't block any connect=
ion=20
from UID 500 to localhost, which is needed for ssh internal work.


;-)

Hope it helps.
Post by Adriana Rodean
Thank you so much,
Adriana
=2D-=20
Ing. Aaron G. Mizrachi P. =20

http://www.unmanarc.com
Mobil 1: + 58 416-6143543
Mobil 2: + 58 424-2412503
BBPIN: 0x 247066C1

--nextPart7105899.8ZvITc8vyd
Content-Type: application/pgp-signature; name=signature.asc
Content-Description: This is a digitally signed message part.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.11 (GNU/Linux)

iEYEABECAAYFAkqDMFsACgkQ2ixydRu83wCOfQCgtxFNNp2Xt3I517x3WR7Xh1eZ
acwAoMmwFMs6HT6o/lWSsj3GGrBIwECz
=C/Wd
-----END PGP SIGNATURE-----

--nextPart7105899.8ZvITc8vyd--
Aarón Mizrachi
2009-08-13 16:13:21 UTC
Permalink
--nextPart1877223.k3uEqkrRyf
Content-Type: text/plain;
charset="iso-8859-15"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
Post by Aarón Mizrachi
Post by Adriana Rodean
Hi,
Is it possible to restrict a client port-forwarding to one port?
For example i want client X to open only port 1037 on server through
port-forwarding, client Y only port 1038 and so on...
How can this be possible?
I use private/public keys authentication.
Client version is openssh3.8p1, is windows client, and server version
is latest openssh on a linux machine.
Can anyone help please?
Indeed. With iptables.
each instance of ssh are excecuted with the UID determined by the SSH
[GWCONN]: IN=3D OUT=3Dwan0 SRC=3D_._._._ DST=3D_._._._ LEN=3D60 TOS=3D0x=
00 PREC=3D0x00
Post by Aarón Mizrachi
TTL=3D64 ID=3D9946 DF PROTO=3DTCP SPT=3D46684 DPT=3D80 WINDOW=3D5840 RES=
=3D0x00 SYN
Post by Aarón Mizrachi
URGP=3D0 OPT (020405B40402080A2E3B8D980000000001030305) UID=3D500 GID=3D5=
00
Post by Aarón Mizrachi
iptables -I OUTPUT -o \! lo -m owner --uid-owner 500 -j LOGDROP
iptables -I OUTPUT -m owner --uid-owner 500 -p tcp -m state --state NEW -m
tcp --dport 80 -j ACCEPT
Sorry for the mistake, my LOGDROP is a "all-in-one" method for logging and=
=20
dropping. You can use: -j DROP instead=20

The sentence without logdrop:

iptables -I OUTPUT -o \! lo -m owner --uid-owner 500 -j DROP
iptables -I OUTPUT -m owner --uid-owner 500 -p tcp -m state --state NEW -m =
tcp=20
=2D-dport 80 -j ACCEPT


;-)
Post by Aarón Mizrachi
you will enable only the port 80 for UID 500 (usernames can be used also).
but remember the -o \! lo, that means that iptables won't block any
connection from UID 500 to localhost, which is needed for ssh internal
work.
;-)
Hope it helps.
Post by Adriana Rodean
Thank you so much,
Adriana
=2D-=20
Ing. Aaron G. Mizrachi P. =20

http://www.unmanarc.com
Mobil 1: + 58 416-6143543
Mobil 2: + 58 424-2412503
BBPIN: 0x 247066C1

--nextPart1877223.k3uEqkrRyf
Content-Type: application/pgp-signature; name=signature.asc
Content-Description: This is a digitally signed message part.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.11 (GNU/Linux)

iEYEABECAAYFAkqDMcEACgkQ2ixydRu83wC7IQCeKeQpeBJ/b0kXnXBJfmzaCjd3
zasAniy/ReYbS27sHpsL9uZBMLYkFTru
=50Df
-----END PGP SIGNATURE-----

--nextPart1877223.k3uEqkrRyf--
Adriana Rodean
2009-08-13 16:22:19 UTC
Permalink
Hi again,

Maybe i didn't expressed myself right.
I want client X to be able to connect with this command: ssh -L
30300:localhost:8080 -R 1037:localhost:55555
Client Y to be able to connect with: ssh -L 30300:localhost:8080 -R
1038:localhost:55555
and so on
but client Y should be forbidden to connect with: ssh -L
30300:localhost:8080 -R 1037:localhost:55555

On the server sshd_config file i already have PermitOpen 8080 so from
the client side only 8080 is accesible on server.

Thank you again,
Sorry for the confusion

Adriana
Joseph Spenner
2009-08-13 16:25:33 UTC
Permalink
Post by Adriana Rodean
Hi,
Is it possible to restrict a client port-forwarding to one
port?
Yes, but you must force key authentication.
Then, in the authorized keys, the 2 entries should look like this:

permitopen="10.16.0.211:1037" ssh-dss AAAAB3NzaC1k...hyHN/a7BHblrelqwejrjqw..first.client.key...etc..elrjwerwer
permitopen="10.16.0.211:1038" ssh-dss weafasdfds..second.client.key..werwerewerwe....etc..



__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
Joseph Spenner
2009-08-14 16:25:54 UTC
Permalink
--- On Thu, 8/13/09, Adriana Rodean <***@gmail.com> wrote:=0A=0A> Hi =
again,=0A> =0A> Maybe i didn't expressed myself right.=0A> I want client X =
to be able to connect with this command:=0A> ssh -L=0A> 30300:localhost:808=
0 -R 1037:localhost:55555=0A> Client Y to be able to connect with: ssh -L=
=0A> 30300:localhost:8080 -R=0A> 1038:localhost:55555=0A> and so on=0A> but=
client Y should be forbidden to connect with:=A0 ssh=0A> -L=0A> 30300:loca=
lhost:8080 -R 1037:localhost:55555=0A=0AFrom what I can tell, your goal is =
to restrict certain REMOTE port forward values. I do not think it is possi=
ble to place restrictions on REMOTE port forwards if port forwarding is ena=
bled in sshd_config. In the authorized_keys, you can list 'permitopen' opt=
ions, but this only applies to LOCAL port forwards.=0A=0A=0A=0A
Adriana Rodean
2009-08-14 16:30:59 UTC
Permalink
Hi,

Thank you so much for the reply :)

Yes that's exactly what i want, restrict certain REMOTE port forward values=
.
If client X has remote port 1037 on the server then client Y should be
forbidden to do remote port-forwarding on port 1037 if client X is not
connected.
Can't it be restricted somehow with iptables or with some Linux commands?
If ssh can't i'm thinking maybe Linux can...
I mean restrict only client X (which is behind a certain ip address)
to listen to port 1037 on the server.

I'm not Linux user, and have minimal knowledge about Linux, but maybe
someone knows...

Thank you again,
Adriana
Post by Adriana Rodean
Hi again,
Maybe i didn't expressed myself right.
ssh -L
30300:localhost:8080 -R 1037:localhost:55555
Client Y to be able to connect with: ssh -L
30300:localhost:8080 -R
1038:localhost:55555
and so on
but client Y should be forbidden to connect with:=A0 ssh
-L
30300:localhost:8080 -R 1037:localhost:55555
From what I can tell, your goal is to restrict certain REMOTE port forwar=
d values. =A0I do not think it is possible to place restrictions on REMOTE =
port forwards if port forwarding is enabled in sshd_config. =A0In the autho=
rized_keys, you can list 'permitopen' options, but this only applies to LOC=
AL port forwards.
Aarón Mizrachi
2009-08-17 17:52:43 UTC
Permalink
--nextPart1485218.X5vV2nrtai
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
Post by Adriana Rodean
Hi again,
Maybe i didn't expressed myself right.
ssh -L
30300:localhost:8080 -R 1037:localhost:55555
Client Y to be able to connect with: ssh -L
30300:localhost:8080 -R
1038:localhost:55555
and so on
but client Y should be forbidden to connect with: ssh
-L
30300:localhost:8080 -R 1037:localhost:55555
From what I can tell, your goal is to restrict certain REMOTE port forward
values. I do not think it is possible to place restrictions on REMOTE po=
rt
forwards if port forwarding is enabled in sshd_config. In the
authorized_keys, you can list 'permitopen' options, but this only applies
to LOCAL port forwards.
I'm sorry, i confused the local port forwarding to server with remote to=20
local. In normal configuration possibilities, as Joseph said, there is no a=
ny=20
possible _simple_ option that i can see.

what i see:

=2D iptables won't be useful on such case, yes, openssh will open this port=
with=20
a process owned by your specific user, but, "-m owner" only applies for OUT=
PUT=20
and POSTROUTING chains. What you need is for INPUT chain.

=2D Internal openssh configuration does not provide you any way to limit wh=
at=20
port are allowed to open by an specific user. Only for outgoing connections=
you=20
can see limits, and you can do it without rsa/dss/... certificates using "M=
atch=20
User" directive on sshd_config

=2D--

But there are other useful possibilities... More complex obviously. I will =
not=20
specify exactly how you can use it, but, hope it helps.

LEVEL: MED. EFFICIENCY: LOW=20
1. Monitor/event script, this script will do something like:

kill -9 $(netstat -anpo | grep ^tcp | grep LISTEN | cut -d"/" -f1 | cut -d=
: -
f2,3 | awk '{printf("echo -n \"%s \"; ps -p %s uh\n",$1,$4);}' | bash | awk=
=20
'{printf("%s %s %s\n",$1,$2,$3);}' | grep unmanarc | grep -v ^1234 | cut -d=
' '=20
=2Df3)

where unmanarc is the username wanted, and the 1234 the port that you allow=
=20
for him.=20

Event will result in system detriment because each bind will launch this=20
command, and even both mechanisms will allow the port binding for a short=20
period of time until the script runs...

LEVEL: MED. EFFICIENCY: MED
2. similar script but creating a dynamic rule on iptables, by default every=
=20
port are restricted, when the script detects a match (username-port), the=20
script will open an INPUT rule allowing this port. In reverse, the port wil=
l=20
be completely useless. This script have to have special mechanism to detect=
=20
when you close the SSH, and close the iptables rule too (-D). But... This=
=20
mechanism is prone to a race condition. An attacker could simply=20

LEVEL: HIGH. EFFICIENCY: HIGH
3. Possibly, the most feasible option: SELinux.

It's possible to enforce a policy defining specials _port_t labels, and=20
restricting specific users domains to bind only on labeled ports on the pro=
gram=20
domain. For that, previously, you have to add to selinux the specific unix=
=20
accounts to these user domains.=20

LEVEL: HIGH. EFFICIENCY: HIGH
4. LD_PRELOAD Method.

LD_PRELOAD method will enable you to create a wrapper for bind. This wrappe=
r=20
could check for "getuid();" and check if a port/user are allowed. This=20
database could be hardcoded or could exist in some specific file.=20

=2D---------------

My recommendation: if you really need an efficient mechanism, try with seli=
nux=20
or ld_preload, if you don't, try with scripts.



;-)

=2D-=20
Ing. Aaron G. Mizrachi P. =20

http://www.unmanarc.com
Mobil 1: + 58 416-6143543
Mobil 2: + 58 424-2412503
BBPIN: 0x 247066C1

--nextPart1485218.X5vV2nrtai
Content-Type: application/pgp-signature; name=signature.asc
Content-Description: This is a digitally signed message part.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.11 (GNU/Linux)

iEYEABECAAYFAkqGfBEACgkQ2ixydRu83wCyjwCgiVSBsQqn+YxnwEimljNivs5O
KecAoLlIuMExwm6W88PCxiutPwHtwico
=qPKG
-----END PGP SIGNATURE-----

--nextPart1485218.X5vV2nrtai--
Joseph Spenner
2009-08-17 17:56:37 UTC
Permalink
Post by Adriana Rodean
From what I can tell, your goal is to restrict certain
REMOTE port forward values. I do not think it is possible
to place restrictions on REMOTE port forwards if port
forwarding is enabled in sshd_config. In the
authorized_keys, you can list 'permitopen' options, but this
only applies to LOCAL port forwards.
Yes that's exactly what i want, restrict certain REMOTE
port forward values.
If client X has remote port 1037 on the server then client
Y should be
forbidden to do remote port-forwarding on port 1037 if
client X is not
connected.
Can't it be restricted somehow with iptables or with some
Linux commands?
If ssh can't i'm thinking maybe Linux can...
I mean restrict only client X (which is behind a certain ip
address)
to listen to port 1037 on the server.
I'm not Linux user, and have minimal knowledge about Linux,
but maybe
someone knows...
Thank you again,
Adriana
Another option could be to create a type of 'portmon' script (port monitor). It could run via root cron, and be looking for user port forwards. Here's an example of what it would see on the sshd (remote) server:

***@slack182:~# lsof -ni |grep user42
sshd 2565 user42 7u IPv4 146804 TCP 127.0.0.1:12345 (LISTEN)

This means user42 has a REMOTE port forward built on port 12345 (notice, it is bound to 127.0.0.1 as remote port forwards always are).
Your script could look for such processes, and if unauthorized ports are present kill the PID(s) associated with them (in this case 2565).
Adriana Rodean
2009-08-17 18:01:36 UTC
Permalink
Hi,

Thank you so much all for the suggestions :)))

Same as Peter i believe that this should be a feature of OpenSSH,
restrict not only local port along with a public key, but remote port
also. This will solve my problem. So please if someone can implement
this would be great...

In the meantime i will try handle with Linux suggestions...
Problem with this approach is that all my clients connect to server
with same user. And from your suggestions i see that i can bind a port
to an user to do the restriction.
Is there any other way to do this? Like bind ip of the client with a port?
Right now only way to identify uniquely a client in my server is by
it's public key in authorized_keys, that's why this feature would of
been nice in ssh to be implemented ...

Thank you so much all,
Adriana
Hi Adriana,
Post by Adriana Rodean
If ssh can't i'm thinking maybe Linux can...
I mean restrict only client X (which is behind a certain ip
address) to listen to port 1037 on the server.
No, if this is going to happen it has to happen in the SSH server.
OpenSSH can do this if each client has their own private SSH key, and
are using it for authentication.
As was suggested you would then disable all other authentication
methods than publickey in sshd, disallow generic port forwarding, and
include a permitopen directive for each client public key in
~/.ssh/authorized_keys
If you wish for it to function differently, keep in mind that one
really wonderful property of open source software such as OpenSSH
(and Linux) is that you yourself, or a contractor, can implement the
functionality you desire, exactly the way you like it. Of course it
is appreciated if any changes are made in agreement with developers,
and contributed back (posted to this mailing list) once finished.
//Peter
_______________________________________________
openssh-unix-dev mailing list
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Loading...