LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Security
User Name
Password
Linux - Security This forum is for all security related questions.
Questions, tips, system compromises, firewalls, etc. are all included here.

Notices


Reply
  Search this Thread
Old 02-22-2011, 05:04 AM   #1
akamikeym
Member
 
Registered: May 2008
Posts: 112

Rep: Reputation: 21
Creating Custom SSH iptable rules for use with UFW


Hi,

I'm trying to set up a firewall at the moment that allows access to my custom SSH port from only my friend's url (they have a static url but dynamic IP). I find iptables a bit of a nightmare and was hoping to use UFW for most of my day to day firewall maintenance and just make a few extra iptable rules to cover exceptional circumstances like this. Fortunately it seems UFW allows this with /etc/ufw/before.rules and /etc/ufw/after.rules.

So at the moment I'm just trying to get the basic iptables rules right. As I say I'm not very good with iptables, does this look right?

Code:
## Drop Default SSH port access With Logging
iptables -N SSH_DEFAULT
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j SSH_DEFAULT
iptables -A SSH_DEFAULT -m recent --set --name SSH -j LOG --log-prefix "SSH_default_port"
iptables -A SSH_DEFAULT -m recent --set --name SSH -j DROP

## Drop Custom SSH port access With Logging
iptables -N SSH_CUSTOM
iptables -A INPUT -p tcp --dport 118118 -m state --state NEW -j SSH_CUSTOM
iptables -A SSH_CUSTOM -m recent --set --name SSH -j LOG --log-prefix "SSH_friend_port"
iptables -A SSH_CUSTOM -m recent --set --name SSH -j DROP

## Allow Custom SSH port from allowed URL with brute force logging
iptables -N SSH_FRIEND
iptables -A SSH_CUSTOM -s my.friends.url.net -j SSH_FRIEND
iptables -A SSH_FRIEND -m recent --set --name SSH -j ACCEPT
iptables -A SSH_FRIEND -m recent --update --seconds 60 --hitcount 4 --name SSH -j LOG --log-prefix "SSH_friend_port_brute_force "
iptables -A SSH_FRIEND -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP
(edit) I thought this was the easy bit!
Oh, well, I've been looking into haw to convert the basic itables to a UFW before.rules. I found that before.rules uses iptables-restore syntax. So I've had a shot at converting the code above to before.rules. (Bearing in mind that I don't know yet whether the code above is right, without some help.)

Code:
#
# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
#   ufw-before-input
#   ufw-before-output
#   ufw-before-forward
#

# Don't delete these required lines, otherwise there will be errors
*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
# End required lines
:SSH_DEFAULT - [0:0]
:SSH_CUSTOM - [0:0]
:SSH_FRIEND - [0:0]
# End Additional chains

# allow all on loopback
-A ufw-before-input -i lo -j ACCEPT
-A ufw-before-output -o lo -j ACCEPT

# quickly process packets for which we already have a connection
-A ufw-before-input -m state --state RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-output -m state --state RELATED,ESTABLISHED -j ACCEPT

# drop INVALID packets (logs these in loglevel medium and higher)
-A ufw-before-input -m state --state INVALID -j ufw-logging-deny
-A ufw-before-input -m state --state INVALID -j DROP

# ok icmp codes
-A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT
-A ufw-before-input -p icmp --icmp-type source-quench -j ACCEPT
-A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT
-A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT
-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT

# allow dhcp client to work
-A ufw-before-input -p udp --sport 67 --dport 68 -j ACCEPT

#
# ufw-not-local
#
-A ufw-before-input -j ufw-not-local

# if LOCAL, RETURN
-A ufw-not-local -m addrtype --dst-type LOCAL -j RETURN

# if MULTICAST, RETURN
-A ufw-not-local -m addrtype --dst-type MULTICAST -j RETURN

# if BROADCAST, RETURN
-A ufw-not-local -m addrtype --dst-type BROADCAST -j RETURN

# all other non-local packets are dropped
-A ufw-not-local -m limit --limit 3/min --limit-burst 10 -j ufw-logging-deny
-A ufw-not-local -j DROP

# allow MULTICAST, be sure the MULTICAST line above is uncommented
-A ufw-before-input -s 224.0.0.0/4 -j ACCEPT
-A ufw-before-input -d 224.0.0.0/4 -j ACCEPT

### Begin Additional Rules ###

# Script kiddie check
#-A ufw-before-input -p tcp --dport 22 -m state --state NEW -j SSH_CHECK
#-A SSH_CHECK -m recent --set --name SSH
#-A SSH_CHECK -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP

## Drop Default SSH port access With Logging
-A ufw-before-input -p tcp --dport 22 -m state --state NEW -j SSH_DEFAULT
-A SSH_DEFAULT -m recent --set --name SSH -j LOG --log-prefix "SSH_default_port"
-A SSH_DEFAULT -m recent --set --name SSH -j DROP

## Drop Custom SSH port access With Logging
-A ufw-before-input -p tcp --dport 118118 -m state --state NEW -j SSH_CUSTOM
-A SSH_CUSTOM -m recent --set --name SSH -j LOG --log-prefix "SSH_friend_port"
-A SSH_CUSTOM -m recent --set --name SSH -j DROP

## Allow Custom SSH port from allowed URL with brute force logging
-A SSH_CUSTOM -s my.friends.url.net -j SSH_FRIEND
-A SSH_FRIEND -m recent --set --name SSH -j ACCEPT
-A SSH_FRIEND -m recent --update --seconds 60 --hitcount 4 --name SSH -j LOG --log-prefix "SSH_friend_port_brute_force"
-A SSH_FRIEND -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP

### End Additional Rules ###

# don't delete the 'COMMIT' line or these rules won't be processed
COMMIT

Last edited by akamikeym; 02-22-2011 at 09:56 AM.
 
Old 02-22-2011, 03:58 PM   #2
win32sux
LQ Guru
 
Registered: Jul 2003
Location: Los Angeles
Distribution: Ubuntu
Posts: 9,870

Rep: Reputation: 380Reputation: 380Reputation: 380Reputation: 380
Using iptables to do hostname-based filtering is a bad idea, IMO. For starters, the lookup is done when the command is executed (and the IP substituted), therefore eliminating the match as soon as your friend's IP changes.

There's a warning about this right in in the manual. From man iptables:
Code:
       [!] -s, --source address[/mask]
              Source specification. Address can be either a network name, a hostname (please note that specifying any name to be resolved with  a  remote
              query  such  as DNS is a really bad idea), a network IP address (with /mask), or a plain IP address.  The mask can be either a network mask
              or a plain number, specifying the number of 1's at the left side of the network mask.  Thus, a mask of 24 is equivalent  to  255.255.255.0.
              A "!" argument before the address specification inverts the sense of the address. The flag --src is an alias for this option.
Have you considered using TCP wrapper instead (or in combination with iptables)? This way the DNS is checked on each connect. It's not a rock-solid solution (security-wise), but it should reduce the amount of times your friend gets locked out due to IP mismatch. That said, if you know your friend's ISP netblock, you also have the option of allowing the whole thing, and when combined with a passwordless login setup, the result would be very, very tight compared to the other approaches.

Last edited by win32sux; 02-22-2011 at 04:00 PM.
 
Old 02-22-2011, 05:17 PM   #3
akamikeym
Member
 
Registered: May 2008
Posts: 112

Original Poster
Rep: Reputation: 21
Well an IP range for their netblock would be nice but I've no idea how to find that out (in the UK). I could use UFW rather than iptables then. I've spent a fruitless day trying to write a firewall using iptables from scratch.

I've already switched to using denyhosts to manage sshd connections, and am setup for passwordless anyway.
 
Old 02-22-2011, 06:22 PM   #4
akamikeym
Member
 
Registered: May 2008
Posts: 112

Original Poster
Rep: Reputation: 21
Well a look on my whois for my externally visible IP address gives me:

Code:
inetnum:        XXX.YYY.0.0 - XXX.YYY.127.255
Which means that assuming this is my netblock there are 128*256=32768 possible users who could access my open (all be it secured) ssh port.
 
Old 02-22-2011, 06:34 PM   #5
win32sux
LQ Guru
 
Registered: Jul 2003
Location: Los Angeles
Distribution: Ubuntu
Posts: 9,870

Rep: Reputation: 380Reputation: 380Reputation: 380Reputation: 380
One other technique you may want to consider is port knocking, but I don't know if it's feasible for you.
 
Old 02-23-2011, 06:16 AM   #6
akamikeym
Member
 
Registered: May 2008
Posts: 112

Original Poster
Rep: Reputation: 21
Urg! Well it's little wonder I get confused about networking. I've tried gathering some more info on my Netblock by attaching directly to my cable modem and when I do so my external IP address range changes! And reverts when put back behind my router.

A traceroute shows what's happening:


Code:
## Direct attachment to cable modem
$traceroute google.co.uk
raceroute: Warning: google.co.uk has multiple addresses; using 74.125.230.145
traceroute to google.co.uk (74.125.230.145), 30 hops max, 52 byte packets
 1  MMMMMMMMMMMMMMMMMM.NNNN.cable.virginmedia.com (82.XX.YY.Z)  8.920 ms  36.155 ms  36.436 ms

## Connection to cable modem via router
$ traceroute google.co.uk
traceroute: Warning: www.google.co.uk has multiple addresses; using 74.125.230.144
traceroute to www.l.google.com (74.125.230.144), 30 hops max, 52 byte packets
 1  router (192.168.A.B)  0.874 ms  0.576 ms  0.573 ms
 2  MMMMMMMMMMMMMMMMMM.NNNN.cable.virginmedia.com (213.DD.EE.F)  10.674 ms  9.106 ms  11.849 ms
(edit)
whois shows a smaller range on the directly connected block 82.XXX.16.0 - 82.XXX.31.255

(31-16+1)*256 = 4096

So it would be nice to use if it means anything to my friend's computer and vice versa. Also since my friend is local and on the same supplier to me does this mean we share a similar IP environment?

Last edited by akamikeym; 02-23-2011 at 06:34 AM.
 
Old 02-23-2011, 06:40 AM   #7
jschiwal
LQ Guru
 
Registered: Aug 2001
Location: Fargo, ND
Distribution: SuSE AMD64
Posts: 15,733

Rep: Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682
I always use the AllowUsers option to only allow connections from certain users. You can also change the port you use for ssh. That will reduce the noise from script kiddies. Also consider using public key authentication. Then someone can't try to guess the username & password.

You can add an option in the first field of the authorized_keys file. One option you can use is from="<canonical hostname>" which will restrict access to a certain host.
 
1 members found this post helpful.
Old 02-23-2011, 06:45 AM   #8
akamikeym
Member
 
Registered: May 2008
Posts: 112

Original Poster
Rep: Reputation: 21
Yeh, I think I'm over worrying. I have key authentication set up on my ssh server and an unconventional ssh port.

(edit) And I'm using denyhost to block badly behaved IP's.

Last edited by akamikeym; 02-23-2011 at 06:47 AM.
 
Old 02-23-2011, 07:51 PM   #9
win32sux
LQ Guru
 
Registered: Jul 2003
Location: Los Angeles
Distribution: Ubuntu
Posts: 9,870

Rep: Reputation: 380Reputation: 380Reputation: 380Reputation: 380
If you really, really wanna make it so that iptables only allows your friend's IP (and you don't wanna do port knocking), there's another way: Set up something like DynDNS on your friend's computer, which gives it a permanent, non-changing DNS address. Then have a cron job on the server periodically check what IP is tied to the DNS address. If the IP hasn't changed, the script exits. If the IP has changed, the old iptables rule gets flushed and one with the new IP is added. In fact, if you're certain only your friend's IP changes (and not the DNS address), then you could do this without having to sign up for a DNS service like the example I linked.

And yes, I do think you're over-worrying, but that can be a healthy habit.
 
Old 02-24-2011, 08:09 AM   #10
akamikeym
Member
 
Registered: May 2008
Posts: 112

Original Poster
Rep: Reputation: 21
win32sux. That thought had occurred to me but I hadn't investigated it fully. I've found a cron script to do just that here. I've not had a chnace to test it yet and am concerned about how it would integrate with UFW. As I understand it UFW has a habit of resetting your firewall rules when it feels like it.
 
Old 02-24-2011, 05:54 PM   #11
win32sux
LQ Guru
 
Registered: Jul 2003
Location: Los Angeles
Distribution: Ubuntu
Posts: 9,870

Rep: Reputation: 380Reputation: 380Reputation: 380Reputation: 380
Why not just ditch UFW completely?
 
Old 02-24-2011, 06:15 PM   #12
akamikeym
Member
 
Registered: May 2008
Posts: 112

Original Poster
Rep: Reputation: 21
Ah, I had a go at that but I didn't have much success with iptables. I find them a complete headache and am never sure if what I've produced is stable or not. This was my recent attempt:

Code:
#!/bin/bash
# IPTABLES is order specific so start with the most general rules and
# move to the specific.
# iptables use:
#   -A  Append one or more rules to the end of the selected chain.
#   -j  what to do if the packet matches rule - target can be a  
#       user-defined  chain or one of the special builtin targets.

# Bit Torrent port
bt_port=12600
# Mediatomb port
mediatomb_port=50500
# SSH port
ssh_port=22 # This will be changed to a non-standard port
# Dubious interface
dub_if="eth0"
# Dubious network
dub_net="192.168.1.0/24"

# Disable port forwarding (there's no NAT on this machine)
echo "0" > /proc/sys/net/ipv4/ip_forward

# Modprobe goes here. I don't know if it's needed

### Clear old iptables ###

# Set defensive policies (only valid for built-in chains)
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# 'Flush' iptables for all built-in chains (i.e. delete all rules for them)
# Note: these Chains cannot be deleted
iptables -F
# Delete user defined chains
iptables -X

### Start of new iptables ###

# Create new user defined chains
#iptables -N TCP
#iptables -N UDP

# Single machine with no NAT (Network Address Translation, AKA Masquerade),
# so Drop all packets looking to be forwared
#iptables -P FORWARD DROP # Already set

# Policy to Accept outward bound packets (don't block packets originating 
# from this machine)
#iptables -P OUTPUT ACCEPT # Already set

# Policy to Drop incomming packets (secure this machine)
#iptables -P INPUT DROP # Already set

# Zero packet and byte counters
#iptables -Z

# Create user defined drop & log table
iptables -N drop-and-log
iptables -A drop-and-log -j LOG --log-level info
iptables -A drop-and-log -j REJECT

# Allow communication on the loopback device 127.0.0.1 (local sockets)
iptables -A INPUT -i lo -j ACCEPT

# Protection against spoofing attacks
#iptables -I INPUT -i $dub_net -s 127.0.0.0/8 -j DROP

## Statefull packet filtering ##
# Drop packets that are invalid
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

# Allow incomming packets that are from established and related connections
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Allow all echo requests from dubious network.
# First packet counts as NEW, the rest are RELATED,ESTABLISHED
iptables -A INPUT -s $dub_net -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT

# Accept mediatomb tcp traffic from dubious network
iptables -A INPUT -p tcp -s $dub_net --dport $mediatomb_port -j ACCEPT

# Accept ssh tcp traffic from dubious network
iptables -A INPUT -p tcp -s $dub_net --dport $ssh_port -j ACCEPT

# Accept bit torrent tcp & udp traffic from everywhere network
iptables -A INPUT --dport $bt_port -j ACCEPT


# Enable kernel builtin source address verification 
echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter

Last edited by akamikeym; 02-24-2011 at 06:18 PM.
 
Old 02-24-2011, 06:30 PM   #13
unixfool
Member
 
Registered: May 2005
Location: Northern VA
Distribution: Slackware, Ubuntu, FreeBSD, OpenBSD, OS X
Posts: 782
Blog Entries: 8

Rep: Reputation: 158Reputation: 158
I use dyndns to allow me to get into my home network when I'm away from home. Works well for me, but I'm using pf on a BSD box that has port 22 exposed to the internet.

Regarding iptables, if you can use ufw, you should be able to use iptables without issues. It's the same concept (they all are)...you just have to get used to the syntax. There are scripts on the interwebz that can help you develop a good iptables script. Me? I bought a book. Once you come up with a good script, it'll hardly ever change.
 
Old 02-28-2011, 11:15 AM   #14
unixfool
Member
 
Registered: May 2005
Location: Northern VA
Distribution: Slackware, Ubuntu, FreeBSD, OpenBSD, OS X
Posts: 782
Blog Entries: 8

Rep: Reputation: 158Reputation: 158
This was marked as solved. OP, can you share your fix?
 
Old 03-02-2011, 02:41 AM   #15
akamikeym
Member
 
Registered: May 2008
Posts: 112

Original Poster
Rep: Reputation: 21
Sorry, only solved in the broadest of senses. I've resolved to have another go at iptables directly based on a generated one here.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
system-config-security and custom iptable rules, where? abolishtheun Linux - Newbie 3 06-18-2009 06:39 PM
iptable rules, your opinions linuxcbon Linux - Security 7 08-16-2008 05:54 PM
IPTable rules RecoilUK Linux - Security 1 05-27-2005 07:25 PM
Verifying IPTable rules... Ateo Linux - Networking 1 02-02-2005 03:33 PM
Help with IPtable Rules aqoliveira Linux - Security 3 12-10-2003 10:00 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Security

All times are GMT -5. The time now is 08:12 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration