The point is, you don't have perfect security, because a system is only as secure as its weakest component. If ssh and/or openvpn can be compromised, someone can hack his way into your server by those means, and if there's something wrong in the netfilter code, you could have packets slip through. Also, if openSSH and/or openVPN are using too weak encryption (various ciphers and hash algorithms are known to be weak), the connections can be attacked as well.
Also, your firewall setup is incomplete and in need of improvement. First of all, you don't have to set OUTPUT to DROP, because that spares you a lot of extra work (you don't have to add policies for outbound packets).
Then, I'd also do a complete overhaul of the firewall rules in general:
- Ditch the
-m state --state xxx
matches in the rules handling SSH, because they are unnecessary (it's the same as if the rules accepted any associated packets directly, albeit a little slower because of the overhead incurred by the match).
- Ditch the
-m state --state xxx
matches in the rules handling openVPN. Since UDP (a connectionless protocol) is used, the match won't even work.
- If you want to retain the default DROP policy for OUTPUT, make sure to exempt the loopback device on the OUTPUT chain so that internal services are able to send packets. Otherwise their transmissions would be blocked as well.
- Your FORWARD section needs improvement: You may have opened the way out for packets arriving via openVPN's tunnel, but the way back is still blocked. Furthermore, only tcp traffic is allowed back because of the
-m state --state ESTABLISHED,RELATED
match, but UDP won't be sent back across the tunnel.
- If you want to access your server via openVPN, you need to add appropriate rules for handling that traffic.
Also, if you want to improve your security even more, rerig openSSH to use pubkey authentication (make sure to disable any authentication scheme requiring username/password) and set up iptables with an automated blacklist:
iptables -N SSH
iptables -N SSH_ABL
iptables -A SSH -m recent --name SSH_ABL --update --seconds 7200 -j DROP
iptables -A SSH -m recent --name SSH --rcheck --seconds 600 --hitcount 3 -j SSH_ABL
iptables -A SSH_ABL -m recent --name SSH_ABL --set -j LOG --log-level warning --log-prefix "ABL: +SSH: "
iptables -A SSH_ABL -j DROP
iptables -A SSH -m recent --name SSH --rcheck --seconds 10 -j LOG --log-level warning --log-prefix "SSH-RATE: "
iptables -A SSH -m recent --name SSH --update --seconds 10 -j REJECT --reject-with icmp-admin-prohibited
iptables -A SSH -m recent --name SSH_ABL --remove -j LOG --log-level warning --log-prefix "ABL: -SSH: "
iptables -A SSH -m recent --name SSH --set -j ACCEPT
iptables -A INPUT -p tcp -m conntrack --ctstate ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp --dport <ssh-port> -m conntrack --ctstate NEW -j SSH
–– Source unknown
Then make sure to not directly ACCEPT any NEW packets meant for SSH, but instead direct them to the SSH chain. This prevents brute-force attacks on SSH.
It's also a good idea to put the rule accepting packets of ESTABLISHED TCP connections early into the rule set so that it is reached quickly, and you don't lose too much time processing those packets. You then only have to insert rules for handling NEW TCP connections (they can be placed late in the chain, because they don't penalize you that much as they are only hit on the SYN packet of a TCP connection). Also make sure to get rid of the default DROP policy for the OUTPUT chain. That way your server is able to establish TCP connections to the Internet, e. g. for updates of its system.
What you'd also want to do is set rules to accept replies to UDP traffic initiated by the server (either generic or limited to specific ports):
iptables -A INPUT -p udp -m conntrack --ctdir REPLY -j ACCEPT
or
iptables -A INPUT -p udp --sport <portnum> -m conntrack --ctdir REPLY -j ACCEPT
This may be necessary for the Network Time Protocol (UDP port 123) and DNS (UDP port 53).
Your firewall rules should then look like these:
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -N SSH
iptables -N SSH_ABL
iptables -A SSH -m recent --name SSH_ABL --update --seconds 7200 -j DROP
iptables -A SSH -m recent --name SSH --rcheck --seconds 600 --hitcount 3 -j SSH_ABL
iptables -A SSH_ABL -m recent --name SSH_ABL --set -j LOG --log-level warning --log-prefix "ABL: +SSH: "
iptables -A SSH_ABL -j DROP
iptables -A SSH -m recent --name SSH --rcheck --seconds 10 -j LOG --log-level warning --log-prefix "SSH-RATE: "
iptables -A SSH -m recent --name SSH --update --seconds 10 -j REJECT --reject-with icmp-admin-prohibited
iptables -A SSH -m recent --name SSH_ABL --remove -j LOG --log-level warning --log-prefix "ABL: -SSH: "
iptables -A SSH -m recent --name SSH --set -j ACCEPT
iptables -t raw -A PREROUTING -i lo -j CT --notrack
iptables -t raw -A OUTPUT -o lo -j CT --notrack
iptables -A INPUT -p tcp -m conntrack --ctstate INVALID -j DROP
iptables -A INPUT -p tcp -m tcp ! --tcp-flags SYN,ACK,FIN,RST SYN -m conntrack --ctstate NEW -j DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 8888 -m conntrack --ctstate NEW -j SSH
iptables -A INPUT -p udp -m multiport --sports 53,123 -m conntrack --ctdir REPLY -j ACCEPT
iptables -A INPUT -i venet0 -p udp --dport 1194 -j ACCEPT
iptables -A INPUT -i venet0 -p icmp --icmp-type 3/4 -j ACCEPT
iptables -A INPUT -j REJECT --reject-with icmp-port-unreachable
iptables -A FORWARD -i venet0 -p tcp -m conntrack --ctstate INVALID -j DROP
iptables -A FORWARD -i venet0 -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i venet0 -p icmp -m conntrack --ctdir REPLY -j ACCEPT
iptables -A FORWARD -i venet0 -p udp -m conntrack --ctdir REPLY -j ACCEPT
# Replace the tun device identifier with the tun device set up by your openVPN.
iptables -A FORWARD -i tun0 -s 10.8.0.0/24 -j ACCEPT
iptables -A FORWARD -j REJECT --reject-with icmp-net-unreachable
iptables -t nat -A POSTROUTING -o venet0 -s 69.147.244.199 -j ACCEPT
iptables -t nat -A POSTROUTING -o venet0 -j SNAT --to-source 69.147.244.199