Close TCP/22 port using yunohost firewall service

Hi everyone,
First, thank you for the amazing work on Yunohost. It really makes it easy to deploy services for me and my family.

I have a question related to the firewall configuration.
I would like to disable ssh access from everywhere except my home IP.
To do so, I created the following file, at /etc/yunohost/hooks.d/post_iptable_rules/95_ssh_from_home:

#!/bin/bash
iptables -w -A INPUT -s <my_home_ip_address> -p tcp --dport=22 -j ACCEPT

exit 0

It is correctly interpreted, as shown with iptables -L -v after reloading Yunohost firewall:

Chain INPUT (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
...
    0     0 ACCEPT     tcp  --  *      *       <home_ip_address>    0.0.0.0/0            tcp dpt:22
...

The next step would be to remove yunohost’s ANY ACCEPT rule for port 22.
However, it does not seem to be possible to do this using yunohost’s tool, by design, to avoid loosing access to a remote box.

I have a backup access to my server using the QEMU novnc console from my VPS provider, and I know what I am doing.
Is there a cleaner way for me to disable the broad access to my ssh port than to manually insert an accept and a DROP rule at the beginning of the iptables firewall policy ?

Thank you in advance for your help,
Best regards,
Saxodwarf

Hmf naively I think tweaking iptables rules directly from your post_iptable_rules is a fine solution ? You could also edit /etc/yunohost/firewall.yml and remove the entries corresponding to port 22 … though not 100% what this do exactly but naively that should do the trick (after a yunohost firewall reload)

Alternatively you could tweak /etc/ssh/sshd_config to whitelist a single IP, pretty sure there’s a mecanism for this (but maybe you’re aiming for a lower-level solution)

I tried directly removing port 22 from /etc/yunohost/firewall.yml, but reloading the firewall restores it.

After taking a look at yunohost/firewall.py, I understood why:

def firewall_reload(skip_upnp=False):
# ...
    # Check if SSH port is allowed
    ssh_port = _get_ssh_port()
    if ssh_port not in firewall_list()['opened_ports']:
        firewall_allow('TCP', ssh_port, no_reload=True)
# ...

I wanted to be sure that there was no built-in way to achieve my goal, but removing the rule from my hook will work for my use case.

Thanks for your suggestions, and have a nice week-end !

EDIT: Just tried it, worked like a charm.
My final hook script is the following:

#!/bin/bash
# Remove IPv4 and IPv6 SSH accept rules
iptables -w -D INPUT -p tcp --dport 22 -j ACCEPT
ip6tables -w -D INPUT -p tcp --dport 22 -j ACCEPT
# Allow SSH from my home IP
iptables -w -A INPUT -s <my_home_ip> -p tcp --dport 22 -j ACCEPT
exit 0
1 Like