Saturday, September 24, 2011

Access your 24-hour IRC client/logbot from anywhere

I use irssi (IRC client) running on a 24/7 server to maintain my IRC presence. When I want to connect to IRC, I ssh into the server, and attach into the running IRC session.

ssh me@myserver.local   # Log into the server
screen -r            # Attach to the irssi session
#(Do stuff)
#CTRL+a, CTRL+d to detach irssi
exit                 # Logout of the server
It's a little different if I want to log in from elsewhere on the internet:
ssh -p PortNumber me@myserver.dyndns.org    # Log into the server
screen -r            # Attach to the irssi session
#(Do stuff)
#CTRL+a, CTRL+d to detach irssi
exit                 # Logout of the server


Here's one way to simplify it:

  1. ssh takes in-session commands:ssh destination "command1; command2"
  2. ssh has a -t flag, forcing a pseudo-terminal connection (screen needs this to work)
  3. bash uses basic if/them logic a couple ways.
  4. determine the network using the 'route' command


So you can set up an ssh command like ssh -t me@myserver 'screen -dr pts-0' to connect to the server and then the screen session. (I already knew that my screen session was at pts-0; it tells you when you detach). When you detach from the screen session (CTRL+a, CTRL+d), the ssh session closes automatically.


One more piece of the puzzle is my network logic - I connect differently if on the LAN or out in the wider world. I use route | grep -q myserver.local to determine if I'm on the home network or not (return is '0' if home network, '1' if internet). Of course, your server name will vary.


The easy, logical result:

LocalNetwork=$(route | grep -q myserver.local)
if $LocalNetwork; then
   ssh -t me@myserver.local 'screen -dr pts-0'
else:
   ssh -t -p PortNumber me@myserver.dyndns.org 'screen -dr pts-0'
fi

We can simplify this even further using bash logical expressions instead of if/then/else statements. It's a single line, but more cryptic:

route | grep -q myserver.local && ssh -t me@myserver.local 'screen -dr pts-0' || \
ssh -t -p PortNumber me@myserver.dyndns.org 'screen -dr pts-0'

Wednesday, September 7, 2011

More useful sshd on the gateway

I need access to my gateway machine (which runs irssi) while out in the world on the internet.


Currently, SSH access from the internet is blocked by firewall. There are a couple ways to enable it. I need to select one, add a secure connection method, and block brute-force methods to crack that connection.


The easiest way is to:

  1. Open port 22 on the firewall
    iptables -A INPUT -p tcp --dport 22 -j ACCEPT
  2. Add a method of blocking brute force attacks
    # Allow incoming ssh attempts for the internet, and add them track them
    #iptables -A INPUT -i ppp0 -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name DEFAULT --rsource
    # After three inbound ssh attempts in three minutes, drop any subsequent attempts until the three minutes expires
    #iptables -A INPUT -i ppp0 -p tcp -m tcp --dport 22 -m state --state NEW -m recent --update --seconds 180 --hitcount 4 --name DEFAULT --rsource -j DROP
  3. Check the settings of /etc/ssh/sshd_config
    # What ports, IPs and protocols we listen for
    Port 22
  4. Check the settings of etc/hosts.allow
    sshd:              ALL
  5. Restart the firewall so the new rules take effect. Restart sshd if any changes to sshd_config or hosts.allow were made.


Alternately, we can tell ssh to listen on a second (unadvertised) port. This may (or may not) be more secure than using firewall rules to block brute force attacks.

  1. Open port 33 on the firewall
    iptables -A INPUT -p tcp --dport 33 -j ACCEPT
  2. Change the settings of /etc/ssh/sshd_config
    # What ports, IPs and protocols we listen for
    Port 22
    Port 33
  3. Check the settings of etc/hosts.allow
    sshd:              ALL
  4. Restart the firewall so the new rules take effect. Restart sshd.
    bash /etc/network/if-up.d/00-firewall
    service restart ssh
    


Since the ddclient package is installed, I can now connect to my server from the internet using:
ssh [--port 33] accountname@myusername.dyndns.org