I have a server which runs a few services. However, for security reasons, I configured the server so that nothing, except for SSH, is accessible from outside.

What I'd like to do instead, though, is to have the server allow access to all its services to anybody who has managed to successfully login via SSH (and once that person disconnects, close all the ports again, except for the SSH port which should remain open).

Is there a way to do this?

I'm using Arch Linux on the server and ufw to manage the firewall.

  • I'd suggest moving this question to stack Overflow, since it will require a script. Also, consider using portknocking.org for extra security – Lizz Jan 25 '13 at 7:05
  • @Lizz: port knocking seems like a cool idea. I'm open to moving it (can't do that without a mod though). – houbysoft Jan 25 '13 at 8:34

You can put commands in ~/.bashrc, anything in there is executed each time a user logs in.

For your commands to only run when logging in via ssh (and not when logging in physically), you can test for the presence of the SSH_CONNECTION environment variable.

| improve this answer | |
  • Right, but I also need it to reclose the ports when the user logs out. I can't just put it in ~/.bash_logout because that doesn't get called if the connection just dies afaik. – houbysoft Jan 25 '13 at 17:16

I wrote a solution for this. It is not perfect, and improvements are welcome. Especially, I think that ~/.bash_logout doesn't get called if the connection dies, but I want the firewall to close itself in those cases too.

In any case, first of all, configure the sudoers file so that your user can run the ufw binary without entering a password.

Then, in ~/.bashrc:

ip=`echo $SSH_CONNECTION | cut -d " " -f 1`
echo "=> Opening the firewall for $ip..."
sudo ufw allow from $ip
echo "=> Done."

In ~/.bash_logout:

ip=`echo $SSH_CONNECTION | cut -d " " -f 1`
echo "=> Closing the firewall for $ip..."
sudo ufw delete allow from $ip
echo "=> Bye."

Again, though, this will only reclose the ports if you terminate your session properly. If somebody knows how to make it close whenever the connection quits / dies / whatever, please edit this answer with your solution.

| improve this answer | |
  • You can write a script that is executed by a cron job that will remove stale IPs from the firewall. Set it to run every five or ten minutes, and then, if a connection is lost, the permission for that IP will be removed within 5 or 10 minutes. There is one problem with your script (and my suggestion too). What happens if the user logs in with two SSH connections (for example, to have two windows open) or if two users log in from the same IP (i.e. from a NAT)? In truth, the best solution would be to set up a real VPN. – Moshe Katz Jan 28 '13 at 21:04
  • @MosheKatz: in those cases you'll just have to close both sessions at the same time, but yes, it's not perfect. I thought about cron, but how would you check for stale IPs? Is there a way to ask the ssh daemon if somebody's connected? – houbysoft Jan 28 '13 at 23:56
  • You can use who --ips to see who is currently logged in. You will need a list of IPs that you have allowed (you may be able to get this from ufw, or you may just keep it yourself using the login and logout scripts). Then, compare the list you have with the output of who and remove any IPs from the firewall (and the list) that aren't in the who output. – Moshe Katz Jan 29 '13 at 5:38
  • @MosheKatz: who --ips gives me unrecognized option '--ips'. I can do just who but that returns a long string containing the domain name, not the IP. There has to be an easier way to get the IPs directly? – houbysoft Jan 29 '13 at 6:51
  • Run man who to see the options you have. You seem to have a different version than I do. – Moshe Katz Jan 29 '13 at 12:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.