For a while I always wondered why fail2ban sometimes put in the same rule twice under iptables:
[root@localhost ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
fail2ban-SSH tcp -- anywhere anywhere tcp dpt:ssh
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
It turns out that when fail2ban service starts, it inserts the fail2ban-ssh rule at the top of your iptables rules; so if you did save of your iptable rules with the fail2ban-ssh rule already inserted, iptables loads its default rules (with fail2ban-ssh in it) and then fail2ban adds it again when it starts.
To fix this, I deleted the fail2ban-ssh rules from iptables and saved those rules; now when my server boots iptables loads without the fail2ban-ssh rule and fail2ban adds it when it starts.