Hi All,
I rarely post to this list; mainly due to a lack of knowledge... but find the email chains fascinating and very informative. I was hoping you could help me out with a few security adjustments on my home development server running Ubuntu 10.10; I would like to achieve the following setup with iptables and maybe a script in sshd_config?
* Accept any connection from within the LAN (192.168.0.*) * Deny All from outside LAN (Except to ports 22, 80, 443, and the range 8000 to 8999)
(the above is admittedly easily done with a google search) but my skills cant quite stretch to finding out how to add an exception to iptables for the IP of any authenticated ssh session and on timeout or disconnect remove that exception. I could then allow external developers to develop on a private port range (7000-7999 - as I do internally) by just connecting to ssh with their public key.
Is this possible?
Festive Tidings
Alex
On Sat, 17 Dec 2011 14:54:20 +0000 Alex Scotton alex.scotton@gmail.com allegedly wrote:
Hi All,
I rarely post to this list; mainly due to a lack of knowledge...
Hi Alex
Lack of knowledge is not a handicap here. In fact, in some cases a little knowledge can be a dangerous thing... ahem.
but find the email chains fascinating and very informative. I was hoping you could help me out with a few security adjustments on my home development server running Ubuntu 10.10; I would like to achieve the following setup with iptables and maybe a script in sshd_config?
- Accept any connection from within the LAN (192.168.0.*)
- Deny All from outside LAN (Except to ports 22, 80, 443, and the
range 8000 to 8999)
This is relatively easy in iptables. I'd suggest something like this:
--------------- iptables file -------------
# iptables firewall # # *filter
# set policy on INPUT to default drop (not reject) :INPUT DROP [0:0]
# but accept forwards and output :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0]
# accept all local loopback connects -A INPUT -i lo -j ACCEPT
# accept established connections (so returns from outgoing connections # are accepted) # -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# accept local net tcp connections. I recommend nominating the ports # acceptable rather than simply accepting any connection. # -A INPUT -p tcp -m tcp -s 192.168.0.0/24 --dports PLACE SOME PORTS OR RANGE HERE -j ACCEPT
# now accept application specific connections from anywhere. # note that you could collapse this to one line by comma delimiting # the port list, but I find this clearer and it is easy to comment # out a single line later if your policy changes. # -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT # but see note below -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT -A INPUT -p tcp -m tcp --dports 8000:8999 -j ACCEPT
# only accept ssh (on port 7000) from known sources # It would be good if you could limit to known sources. Again, # one line per source address makes things clear and allows # easy edits later.
-A INPUT -p tcp -s SOURCE_ADDRESS_1 -m tcp --dport 7000 -j ACCEPT -A INPUT -p tcp -s SOURCE_ADDRESS_2 -m tcp --dport 7000 -j ACCEPT
# allow ping inbound (it helps the ssh users to know if the machine # is up). # -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
# I like to log other attempts. You don't have to, but it can be # interesting.
# now log before (policy) drop start of all other incoming TCP packets # -A INPUT -p tcp -m state --state NEW -j LOG --log-level emerg --log-prefix "firewall "
# and log (policy) drop of all UDP packets -A INPUT -p udp -m state --state NEW -j LOG --log-level emerg --log-prefix "firewall "
COMMIT
# end
--------------- end iptables -------------
Now your syslog conf file needs a couple of lines line to allow the firewall logging thusly:
# log iptables connections to separate file # kern.=emerg -/var/log/firewall
# and other kernel messages go to kern.log # kern.!=emerg -/var/log/kern.log
but don't forget to comment out the standard line:
#*.emerg *
or you will get a flood of iptables logs to your console!
(the above is admittedly easily done with a google search) but my skills cant quite stretch to finding out how to add an exception to iptables for the IP of any authenticated ssh session and on timeout or disconnect remove that exception. I could then allow external developers to develop on a private port range (7000-7999 - as I do internally) by just connecting to ssh with their public key.
[Note]. I'm not sure why you want a range of ports for ssh. Change the default port by all means, but you only need one. I'm also unclear why you want to allow connections to ports 22 from outside as well as moving the ssh listener to port 7000 (so the iptables example above where I have placed the marker "see note" would allow anyone outside to connect to ssh on port 22 (so long as they can authenticate)
Nor am I sure how you expect to see an ssh session before iptables has permitted the connection. If there is no session, then you can't add/remove a line based on that connection.
But if you simply limit connections to those from known sources and with known ssh keys you should be pretty safe (for some definition of safe).
HTH
Mick
---------------------------------------------------------------------
The text file for RFC 854 contains exactly 854 lines. Do you think there is any cosmic significance in this?
Douglas E Comer - Internetworking with TCP/IP Volume 1
http://www.ietf.org/rfc/rfc854.txt ---------------------------------------------------------------------
Hi Mick,
Thanks for the reply, the IP Tables example is a great help; I don't think I was very clear with what I want to achieve with SSH, in an attempt to be brief.
I don't want to limit the connections to SSH or change the SSH port, I would like it so that upon a successful connection to the SSH Daemon (i.e. someone authenticates with their public key) that their IP address is added to IPTables to allow access to the port range 7000-7999.
To explain why, recently, I have taken to Node.JS development and at the moment it isn't a very secure platform (http://nosql.mypopescu.com/post/14453905385/attacking-nosql-and-node-js-serv... - scary considering I've been running these on public ports up til now) but a friend and I develop on my home server and I would like to allow us to develop node on private port ranges, and then move these to the 8000-8999 range once they are in "production". However, he is "out in the sticks" and quite often has an IP change, also, I quite often uses my mobile over 3g to test/debug; so it'd be excellent if we could just 1 click login to ssh and be automatically excluded from the firewall.
I could probably write a node app to monitor the ssh or fail2ban logs and update the firewall configs etc, but I assume their is an in-built and more efficient means (that wouldn't take me a few days of string manipulation coding) to do it.
With Thanks and Festive Tidings
Alex
On Tue, Dec 20, 2011 at 8:13 PM, mick mbm@rlogin.net wrote:
On Sat, 17 Dec 2011 14:54:20 +0000 Alex Scotton alex.scotton@gmail.com allegedly wrote:
Hi All,
I rarely post to this list; mainly due to a lack of knowledge...
Hi Alex
Lack of knowledge is not a handicap here. In fact, in some cases a little knowledge can be a dangerous thing... ahem.
but find the email chains fascinating and very informative. I was hoping you could help me out with a few security adjustments on my home development server running Ubuntu 10.10; I would like to achieve the following setup with iptables and maybe a script in sshd_config?
- Accept any connection from within the LAN (192.168.0.*)
- Deny All from outside LAN (Except to ports 22, 80, 443, and the
range 8000 to 8999)
This is relatively easy in iptables. I'd suggest something like this:
--------------- iptables file -------------
# iptables firewall # # *filter
# set policy on INPUT to default drop (not reject) :INPUT DROP [0:0]
# but accept forwards and output :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0]
# accept all local loopback connects -A INPUT -i lo -j ACCEPT
# accept established connections (so returns from outgoing connections # are accepted) # -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# accept local net tcp connections. I recommend nominating the ports # acceptable rather than simply accepting any connection. # -A INPUT -p tcp -m tcp -s 192.168.0.0/24 --dports PLACE SOME PORTS OR RANGE HERE -j ACCEPT
# now accept application specific connections from anywhere. # note that you could collapse this to one line by comma delimiting # the port list, but I find this clearer and it is easy to comment # out a single line later if your policy changes. # -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT # but see note below -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT -A INPUT -p tcp -m tcp --dports 8000:8999 -j ACCEPT
# only accept ssh (on port 7000) from known sources # It would be good if you could limit to known sources. Again, # one line per source address makes things clear and allows # easy edits later.
-A INPUT -p tcp -s SOURCE_ADDRESS_1 -m tcp --dport 7000 -j ACCEPT -A INPUT -p tcp -s SOURCE_ADDRESS_2 -m tcp --dport 7000 -j ACCEPT
# allow ping inbound (it helps the ssh users to know if the machine # is up). # -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
# I like to log other attempts. You don't have to, but it can be # interesting.
# now log before (policy) drop start of all other incoming TCP packets # -A INPUT -p tcp -m state --state NEW -j LOG --log-level emerg --log-prefix "firewall "
# and log (policy) drop of all UDP packets -A INPUT -p udp -m state --state NEW -j LOG --log-level emerg --log-prefix "firewall "
COMMIT
# end
--------------- end iptables -------------
Now your syslog conf file needs a couple of lines line to allow the firewall logging thusly:
# log iptables connections to separate file # kern.=emerg -/var/log/firewall
# and other kernel messages go to kern.log # kern.!=emerg -/var/log/kern.log
but don't forget to comment out the standard line:
#*.emerg *
or you will get a flood of iptables logs to your console!
(the above is admittedly easily done with a google search) but my skills cant quite stretch to finding out how to add an exception to iptables for the IP of any authenticated ssh session and on timeout or disconnect remove that exception. I could then allow external developers to develop on a private port range (7000-7999 - as I do internally) by just connecting to ssh with their public key.
[Note]. I'm not sure why you want a range of ports for ssh. Change the default port by all means, but you only need one. I'm also unclear why you want to allow connections to ports 22 from outside as well as moving the ssh listener to port 7000 (so the iptables example above where I have placed the marker "see note" would allow anyone outside to connect to ssh on port 22 (so long as they can authenticate)
Nor am I sure how you expect to see an ssh session before iptables has permitted the connection. If there is no session, then you can't add/remove a line based on that connection.
But if you simply limit connections to those from known sources and with known ssh keys you should be pretty safe (for some definition of safe).
HTH
Mick
The text file for RFC 854 contains exactly 854 lines. Do you think there is any cosmic significance in this?
Douglas E Comer - Internetworking with TCP/IP Volume 1
http://www.ietf.org/rfc/rfc854.txt
On Tue, 20 Dec 2011 21:56:18 +0000 Alex Scotton alex.scotton@gmail.com allegedly wrote:
Hi Mick,
Thanks for the reply, the IP Tables example is a great help; I don't think I was very clear with what I want to achieve with SSH, in an attempt to be brief.
I don't want to limit the connections to SSH or change the SSH port, I would like it so that upon a successful connection to the SSH Daemon (i.e. someone authenticates with their public key) that their IP address is added to IPTables to allow access to the port range 7000-7999.
Ah. Sorry, I misunderstood your requirement.
Ordinarily I'd say just tunnel the connection over ssh, but since you want to connect to a range of ports rather than a single port, then I suggest you look at openvpn. Someone else on the mailing list (Martin Brooks I believe) has even written a useful openvpn "howto" at http://hinterlands.org/wiki/index.php/OpenVPNQuickstart
HTH
Mick ---------------------------------------------------------------------
The text file for RFC 854 contains exactly 854 lines. Do you think there is any cosmic significance in this?
Douglas E Comer - Internetworking with TCP/IP Volume 1
http://www.ietf.org/rfc/rfc854.txt ---------------------------------------------------------------------
On Wed, Dec 21, 2011 at 11:20 AM, mick mbm@rlogin.net wrote:
Ah. Sorry, I misunderstood your requirement.
Ordinarily I'd say just tunnel the connection over ssh, but since you want to connect to a range of ports rather than a single port, then I suggest you look at openvpn. Someone else on the mailing list (Martin Brooks I believe) has even written a useful openvpn "howto" at http://hinterlands.org/wiki/index.php/OpenVPNQuickstart
HTH
No problem - on my second read of my original email I was not clear at all. :(
The problem with VPN is it comes with a whole host of client-end setup on an array of environments.
I would just write a node script to monitor the ssh auth logs and prepend the iptables rules but that would require the node server having the ability to become a SU :S
or I could write a bash script daemon to monitor an output file of a node instance and issue the commands, and again :S
I'm sure an investigation into the source of fail2ban will return some results, I will post back if I answer my own question :)
KR and thanks for your time
It sounds like you might be interested in Port Knocking: http://en.wikipedia.org/wiki/Port_knocking
Tim.
On Wed, 21 Dec 2011 16:33:20 +0000 Alex Scotton alex.scotton@gmail.com allegedly wrote:
No problem - on my second read of my original email I was not clear at all. :(
The problem with VPN is it comes with a whole host of client-end setup on an array of environments.
I would just write a node script to monitor the ssh auth logs and prepend the iptables rules but that would require the node server having the ability to become a SU :S
or I could write a bash script daemon to monitor an output file of a node instance and issue the commands, and again :S
I'm sure an investigation into the source of fail2ban will return some results, I will post back if I answer my own question :)
Alex
Whilst setting up a VPN may seem like a lot of unnecessary faffing about, I strongly recommend that you give its some serious consideration. You /really/ don't want to be writing any setuid scripts to mess with your iptables rules.
Mick
---------------------------------------------------------------------
The text file for RFC 854 contains exactly 854 lines. Do you think there is any cosmic significance in this?
Douglas E Comer - Internetworking with TCP/IP Volume 1
http://www.ietf.org/rfc/rfc854.txt ---------------------------------------------------------------------
On 20 December 2011 21:56, Alex Scotton alex.scotton@gmail.com wrote:
I don't want to limit the connections to SSH or change the SSH port, I would like it so that upon a successful connection to the SSH Daemon (i.e. someone authenticates with their public key) that their IP address is added to IPTables to allow access to the port range 7000-7999.
Hey Dude,
I don't think having a script run post SSH authentication is a good idea as it's going to need root access (just my two pence).
Instead, what I have on a home server is some slightly loose rules. Set your sshd config to not allow root access, only your two user accounts, have crazy complex non-dictionary passwords, disconnect after 3 bad logins etc. All the usual gaff.
Then, the following iptables rules will block an IP that is brute forcing your sshd but allow your specified users; #Block automated SSH attacks iptables -N SSHSCAN iptables -A INPUT -s 1.2.3.4/32 -p tcp -m tcp --dport 22 -j ACCEPT iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j SSHSCAN iptables -A SSHSCAN -m recent --set --name SSH iptables -A SSHSCAN -m recent --update --seconds 300 --hitcount 3 --name SSH -j LOG --log-level info --log-prefix "SSH SCAN blocked: " iptables -A SSHSCAN -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP
I've allowed SSH access for my known good IP, 1.2.3.4. You could add few loose rules in for your remote friend. Get his WAN IP and look it up with a whois lookup, find the subnet/ip block its part off and add that subnet as an allowed IP range. This will cover 99% of your friends IP changes strait of the bat. The odds of another broadband customer on your friends ISP in the same subnet attacking your box are 1 in a ga-jillion (real number!) so I think it's an acceptable risk (which should be balanced by the previously mentioned long passwords and no root logins etc).
Also, have you thought about SSH tunnels? You could just open SSH access, then you can your friend can tunnel in to the other ports you mentioned?
Ts & Cs: I'm some what hung over so this may not be the best advise :S
On Thu, Dec 22, 2011 at 01:46:36PM +0000, James Bensley wrote:
Ts & Cs: I'm some what hung over so this may not be the best advise :S
Or install denyhosts. http://denyhosts.sourceforge.net/
Adam
Hi James,
Cheers dude, I have the usual suspects protecting SSH: fail2ban (on 3 unsuccesful attemps and blocked for 24hours), Snort (with the appropriate plugin running to attach to IPtables and block any suspicious activity) SSH Config: root login disabled and approved users only / no password entry (just public keys)
Can I ask though, why is it a bad idea to have a script running as root? accordingly, fail2ban runs in this way, and of course many other daemons, so long as it is only executable etc by root, and has no "interface" surely it's secure?
Thank for the info on subnets, this will definitely provide a temporary work around, at the moment I am half way through writing a node module that is currently detecting SSH logins and logging the info required by iptables, I just need to integrate this https://github.com/pkrumins/node-iptables module, and I will be able to edit iptable rules; but as you have suggested this needs to be executed as root (and i'm almost certain running a node instance as root is a dodgy activity); I cannot beleive there is not an exisiting "secure" script on ubuntu that I can manipulate to acheive my needs
SSH Tunnels are probably the way to go with it; I'm trying to simplify something that is already pretty simple by the looks of the responses :)
I dunno, maybe I should give up with the obsession :) hehe
Cheer and a Merry Christmas to you all
Alex
On Thu, Dec 22, 2011 at 1:46 PM, James Bensley jwbensley@gmail.com wrote:
On 20 December 2011 21:56, Alex Scotton alex.scotton@gmail.com wrote:
I don't want to limit the connections to SSH or change the SSH port, I would like it so that upon a successful connection to the SSH Daemon (i.e. someone authenticates with their public key) that their IP address is added to IPTables to allow access to the port range 7000-7999.
Hey Dude,
I don't think having a script run post SSH authentication is a good idea as it's going to need root access (just my two pence).
Instead, what I have on a home server is some slightly loose rules. Set your sshd config to not allow root access, only your two user accounts, have crazy complex non-dictionary passwords, disconnect after 3 bad logins etc. All the usual gaff.
Then, the following iptables rules will block an IP that is brute forcing your sshd but allow your specified users; #Block automated SSH attacks iptables -N SSHSCAN iptables -A INPUT -s 1.2.3.4/32 -p tcp -m tcp --dport 22 -j ACCEPT iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j SSHSCAN iptables -A SSHSCAN -m recent --set --name SSH iptables -A SSHSCAN -m recent --update --seconds 300 --hitcount 3 --name SSH -j LOG --log-level info --log-prefix "SSH SCAN blocked: " iptables -A SSHSCAN -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP
I've allowed SSH access for my known good IP, 1.2.3.4. You could add few loose rules in for your remote friend. Get his WAN IP and look it up with a whois lookup, find the subnet/ip block its part off and add that subnet as an allowed IP range. This will cover 99% of your friends IP changes strait of the bat. The odds of another broadband customer on your friends ISP in the same subnet attacking your box are 1 in a ga-jillion (real number!) so I think it's an acceptable risk (which should be balanced by the previously mentioned long passwords and no root logins etc).
Also, have you thought about SSH tunnels? You could just open SSH access, then you can your friend can tunnel in to the other ports you mentioned?
Ts & Cs: I'm some what hung over so this may not be the best advise :S
-- James. http://www.jamesbensley.co.cc/
main@lists.alug.org.uk http://www.alug.org.uk/ http://lists.alug.org.uk/mailman/listinfo/main Unsubscribe? See message headers or the web site above!
On Fri, 23 Dec 2011 12:10:47 +0000 Alex Scotton alex.scotton@gmail.com allegedly wrote:
Can I ask though, why is it a bad idea to have a script running as root? accordingly, fail2ban runs in this way, and of course many other daemons, so long as it is only executable etc by root, and has no "interface" surely it's secure?
there are a bunch of reasons setuid scripts are bad idea. A good starting explanation is at:
http://www.faqs.org/faqs/unix-faq/faq/part4/section-7.html
I'd also recommend reading something like Practical Unix Security by Garfinkel and Spafford
Mick
---------------------------------------------------------------------
The text file for RFC 854 contains exactly 854 lines. Do you think there is any cosmic significance in this?
Douglas E Comer - Internetworking with TCP/IP Volume 1
http://www.ietf.org/rfc/rfc854.txt ---------------------------------------------------------------------
On 17 Dec 14:54, Alex Scotton wrote:
Hi All,
Hey ho! (Yeah, I know, it took me till the new year to reply... but in fairness, I only read this this morning! I was on holiday and not infront of a keyboard mostly!)
I rarely post to this list; mainly due to a lack of knowledge... but find the email chains fascinating and very informative.
Lack of knowledge isn't a problem - and questions are always welcomed...
I was hoping you could help me out with a few security adjustments on my home development server running Ubuntu 10.10; I would like to achieve the following setup with iptables and maybe a script in sshd_config?
- Accept any connection from within the LAN (192.168.0.*)
- Deny All from outside LAN (Except to ports 22, 80, 443, and the
range 8000 to 8999)
That's fairly simple to do to start with :)
(the above is admittedly easily done with a google search) but my skills cant quite stretch to finding out how to add an exception to iptables for the IP of any authenticated ssh session and on timeout or disconnect remove that exception. I could then allow external developers to develop on a private port range (7000-7999 - as I do internally) by just connecting to ssh with their public key.
OK - so with a bit of playing, I reckon this can mostly be done using nothing more than iptables...
Note: This only covers the last bit!
here goes nothing...
# For hosts that are in the recent table named sshlogin allow # connections to ports 7000 -> 7999 for up to 30 minutes after the last # interactive packet from the ssh connection iptables -I INPUT 1 --proto tcp \ -m multiport --destination-ports 7000:7999 \ -m recent --rcheck --name sshlogin --seconds 1800 \ -j ACCEPT
# For anything but the LAN and things matched by the rule above, reject # packets to ports 7000 -> 7999 iptables -I INPUT 2 --proto tcp \ -m multiport --destination-ports 7000:7999 \ ! --source 192.168.0.0/24 \ -j REJECT
# When ssh has established a connection it will send back a tos of 0x10 # in the interactive packets, we use that to update the sshlogin recent # table - this only gets set (as far as I can tell) after a successful # login. We check it server side rather than client side because I trust # the server to be more sane. iptables -A OUTPUT --proto tcp \ -m tos --tos 0x10 \ --source-port 22 \ -m recent --update --rdest --name sshlogin \ -j ACCEPT
I haven't done extensive testing on that though, it appeared to work for me quite nicely though!
If you need the rest of the firewall written too, then I suspect I can do that later tonight ;)
Cheers,