LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Security (http://www.linuxquestions.org/questions/linux-security-4/)
-   -   Prevent ssh to other machines (http://www.linuxquestions.org/questions/linux-security-4/prevent-ssh-to-other-machines-611627/)

cizzi 01-06-2008 10:48 PM

Prevent ssh to other machines
 
I will be running a shell service and would like to know whats the best way to implement restriction to where usersc connected to the public linux server can ssh to? For example, I do NOT want them to be able to see or access any machines on the internal (192.168.1.x) network subnet. Any help would be appreciated. Thanks.

MS3FGX 01-06-2008 11:03 PM

What are users allowed to do then?

You could, for example, limit their PATH variable or permissions in such a way that they can only execute specific binaries you have allowed. But if the users are to have a lot of freedom (without connecting to other machines) this could be tedious.

Uncle_Theodore 01-06-2008 11:07 PM

I think, the easiest way to do it is something along the lines of
iptables -A OUTPUT -p tcp -d 192.168.0.0/24 --destination-port 22 -j DROP

cizzi 01-06-2008 11:11 PM

Thanks for the reply, if I issue that statement will I still be able to see the other machines? (me as in root or my username). I dont want to lock myself out since i dont know how to reverse that statement. So I thought i'd ask you before typing it in. I have a book on iptables in the mail that i ordered.

Thanks

Uncle_Theodore 01-06-2008 11:17 PM

Quote:

Originally Posted by cizzi (Post 3013919)
Thanks for the reply, if I issue that statement will I still be able to see the other machines? (me as in root or my username). I dont want to lock myself out since i dont know how to reverse that statement. So I thought i'd ask you before typing it in. I have a book on iptables in the mail that i ordered.

Thanks

If you issue this command on the client machine, nobody on this machine will be able to conect to a ssh server on your private network. But if a ssh server is running on that client machine, it will accept connections from everywhere (if another rule doesn't prevent it).

win32sux 01-07-2008 01:13 AM

You could do it by usernames if you want.

Like, make a couple rules to allow root and your non-root account, and then a rule to deny everyone else. Example:
Code:

iptables -A OUTPUT -d 192.168.1.0/24 -m owner --uid-owner root -j ACCEPT
iptables -A OUTPUT -d 192.168.1.0/24 -m owner --uid-owner cizzi -j ACCEPT
iptables -A OUTPUT -d 192.168.1.0/24 -j REJECT

Whether this will work or not would depend on what sort of iptables rules you have above these. Maybe post your config here for us to check before you do any of this? Just to be safe.
Code:

iptables -nvL

cizzi 01-07-2008 08:33 AM

This is what I have now:

root@silver1:/home# iptables -nvL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

win32sux 01-07-2008 11:31 AM

Quote:

Originally Posted by cizzi (Post 3014349)
This is what I have now:

root@silver1:/home# iptables -nvL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Okay, your three filter chains are completely clear. You should be fine executing the commands I posted in the order I posted them in. Make sure to replace "cizzi" with the actual username of your non-root account, and please re-post the "iptables -nvL" output after you executed the commands. Actually, allow me to add one command as a precaution, in case you need to connect to the box from the LAN:
Code:

iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -d 192.168.1.0/24 -m owner --uid-owner root -j ACCEPT
iptables -A OUTPUT -d 192.168.1.0/24 -m owner --uid-owner cizzi -j ACCEPT
iptables -A OUTPUT -d 192.168.1.0/24 -j REJECT

Also, keep in mind that the firewall configuration these commands create will be gone with a reboot unless you actually save it. The preferred saving method sort of varies depending on the distro and the user. Some people instead choose to simply add the commands to their startup scripts.

NOTE: Packets generated by SUID root programs such as ping will match the second rule.

cizzi 01-07-2008 12:31 PM

It works great. I added it to my startup scripts as well. Here's the output you requested.

root@silver1:~# iptables -nvL
Chain INPUT (policy ACCEPT 142 packets, 14251 bytes)
pkts bytes target prot opt in out source destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain OUTPUT (policy ACCEPT 8 packets, 1108 bytes)
pkts bytes target prot opt in out source destination
108 21187 ACCEPT 0 -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
28 3061 ACCEPT 0 -- * * 0.0.0.0/0 192.168.1.0/24 OWNER UID match 0
0 0 ACCEPT 0 -- * * 0.0.0.0/0 192.168.1.0/24 OWNER UID match 1000
0 0 REJECT 0 -- * * 0.0.0.0/0 192.168.1.0/24 reject-with icmp-port-unreachable
root@silver1:~#

The only thing is, explain to me the first line, you said something about allowing me to connect from boxes on the LAN? Why would it block incomming requests from other machines from the LAN if I didnt issue the first iptables command?

win32sux 01-07-2008 12:57 PM

Quote:

Originally Posted by cizzi (Post 3014598)
It works great.

Great! I assume you tested it, right? Like, by trying to connect to the LAN as some other user and stuff.

Quote:

I added it to my startup scripts as well. Here's the output you requested.

root@silver1:~# iptables -nvL
Chain INPUT (policy ACCEPT 142 packets, 14251 bytes)
pkts bytes target prot opt in out source destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain OUTPUT (policy ACCEPT 8 packets, 1108 bytes)
pkts bytes target prot opt in out source destination
108 21187 ACCEPT 0 -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
28 3061 ACCEPT 0 -- * * 0.0.0.0/0 192.168.1.0/24 OWNER UID match 0
0 0 ACCEPT 0 -- * * 0.0.0.0/0 192.168.1.0/24 OWNER UID match 1000
0 0 REJECT 0 -- * * 0.0.0.0/0 192.168.1.0/24 reject-with icmp-port-unreachable
root@silver1:~#
Looks good.

Quote:

The only thing is, explain to me the first line, you said something about allowing me to connect from boxes on the LAN? Why would it block incomming requests from other machines from the LAN if I didnt issue the first iptables command?
Okay, imagine the first rule isn't there. Now let's say for example you have a service for the LAN running on this box. Let's say it's Privoxy, running as user privoxy.

So a LAN client tries to start a connection with the Privoxy daemon. The packets coming into the box from the client will get sent to ACCEPT by the INPUT chain's policy. But the packets returning to the client (OUTPUT chain, state ESTABLISHED, destination 192.168.1.0/24, etc.) wouldn't match the first rule, since they weren't generated by a process with UID 0 ownership. They also wouldn't match the second rule, since they weren't generated by a process with UID 1000 ownership either. But they would in fact match the third rule, since that rule matches against any packet with destination 192.168.1.0/24 - regardless of process UID. So these packets will consequently get sent to REJECT, and Privoxy won't be able to communicate with the client.

By adding a rule matching packets in state ESTABLISHED, we make sure that any outgoing packets which are already a part of an existing connection (such as that which was started by the LAN client in the example) will get sent to ACCEPT regardless of UID ownership. The same applies with RELATED but it's for packets which might not be part of the original connection itself, yet necessary in order for the original connection to work as expected (ICMP error, FTP data, etc).

cizzi 01-07-2008 04:13 PM

So as long as the computers on my LAN are connected to the linux box they will have access even if they're not connecting as root or UID 1000 to the linux box? And the only way for outside users to connect is through my firewall through the linux server with the iptable rules in effect (the ones I added) right?

win32sux 01-07-2008 04:20 PM

Quote:

Originally Posted by cizzi (Post 3014822)
So as long as the computers on my LAN are connected to the linux box they will have access even if they're not connecting as root or UID 1000 to the linux box?

Yes, Linux can only tell the UID of the program which generated outgoing packets. The rules I've given you do not add any restrictions at all for incoming packets. So if someone was able to connect from the LAN to something on your server before my rules were executed, they should be able to connect after they are executed also.

Quote:

And the only way for outside users to connect is through my firewall through the linux server with the iptable rules in effect (the ones I added) right?
Yes, outsiders would still need to be forwared by your LAN's router in order to reach the server. With these rules, users which SSHed into the server wouldn't be able to connect to boxes on the LAN, but they would be able to connect to boxes on the WAN/Internet (assuming your router allows them to do so).

cizzi 01-07-2008 05:18 PM

If I wanted to restrict where they could ssh to from my linux box, how would I do that? Could you give me an example.

win32sux 01-07-2008 06:01 PM

Quote:

Originally Posted by cizzi (Post 3014886)
If I wanted to restrict where they could ssh to from my linux box, how would I do that? Could you give me an example.

Well, technically what I already posted is an example of that. You've restricted them to only connect to non-LAN IPs. They would not only be able to SSH to the WAN, but also FTP, HTTP, etc. But, let's say that you didn't want them to be able to start any connections anywhere, with the exception of SSH connections to a certain WAN IP. You could do that by adding one rule to the previous example:
Code:

iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -d 192.168.1.0/24 -m owner --uid-owner root -j ACCEPT
iptables -A OUTPUT -d 192.168.1.0/24 -m owner --uid-owner cizzi -j ACCEPT
iptables -A OUTPUT -d 192.168.1.0/24 -j REJECT
iptables -A OUTPUT -p TCP -d ! 200.123.200.123 --dport 22 -j REJECT

This rule basically says "send to REJECT any packet which doesn't have 200.123.200.123 as its destination IP and 22 as its destination port".

But there is a problem here. What happens when root or cizzi want to SSH (or FTP, HTTP, etc.) somewhere else on the WAN? They won't be able to, as their packets will match that rule we just added. So what we could do is modify their prior rules to make them less specific - by eliminating the destination matches:
Code:

iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner root -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner cizzi -j ACCEPT

iptables -A OUTPUT -d 192.168.1.0/24 -j REJECT
iptables -A OUTPUT -p TCP -d ! 200.123.200.123 --dport 22 -j REJECT

Now root and cizzi have full outbound access once again. But notice that the rule before the last one is now redundant, as the last rule would send to REJECT any packets destined to the LAN anyways. So we could get rid of that:
Code:

iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner root -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner cizzi -j ACCEPT
iptables -A OUTPUT -p TCP -d ! 200.123.200.123 --dport 22 -j REJECT

Now we have a setup where root and cizzi can connect to anything, and anyone else can only SSH to 200.123.200.123.

But we still forgot something - local packets. A common approach is to simply allow all outgoing traffic on localhost, like:
Code:

iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner root -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner cizzi -j ACCEPT
iptables -A OUTPUT -p TCP -d ! 200.123.200.123 --dport 22 -j REJECT

Of course, this is over-simplistic, as it's just an example. In reality one would most likely want to tighten-up the rules for the loopback interface on box people are SSHing into from all over the place.

Now, let's say you want to let people connect to a certain FTP server on the WAN, HTTP server the WAN, and SSH server on the LAN. That might look like:
Code:

iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner root -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner cizzi -j ACCEPT
iptables -A OUTPUT -p TCP -d 200.123.200.123 --dport 21 -j ACCEPT
iptables -A OUTPUT -p TCP -d 230.13.231.233 --dport 80 -j ACCEPT
iptables -A OUTPUT -p TCP -d 192.168.1.114 --dport 22 -j ACCEPT

iptables -A OUTPUT -j REJECT

Now they can connect to the FTP port on 200.123.200.123, the HTTP port on 230.13.231.233, and the SSH port on 192.168.1.114, while being denied access to anything else.

Please note that these are only examples and are not intended for you to run them as is.

Uncle_Theodore 01-07-2008 06:03 PM

The last rule can be replaced with setting the OUTPUT policy to DROP, which is somewhat preferred way...


All times are GMT -5. The time now is 09:52 AM.