Setting alternate ssh port in firewall

Greetings –

Been using RHEL and CentOS for a long time - given the usual ‘stuff’ about CentOS 8, decided to ‘upgrade’ from CentOS 7 to AlmaLinux 8. Practiced a bit first bt=y installing AL8 into a VM, but today, pulled the trigger on a ‘real’ install. [Tried leapp - crashed and burned, so did it the ‘clean install way’].

All good, but the firewall config/setup for RHEL/AL8 is quite different than for RHEL/CentOS7. I’m struggling with how to do a couple of things:

1\ I tweaked the sshd.conf file to have the system listening on an alternate port (say, port 1234).

2\ in the firewall setup (using cockpit), I can see 1234 listed as an ‘additional port’, but doesn’t seem to be any way to edit the rule(s) for said port.

3\ I do see port 22, but I want to create a rule that rejects anything hitting that port.

So, in simple summary - have sshd listen on 1234, not listen on 22, have 1234 accept new TCP connections, and have 22 reject everything.

Any help/suggestions/points to the obvious much appreciated. At some point, this machine will be outward facing, so want to make sure I have the firewall rules for ssh connection locked down.

Thanks in advance…

Both 7 and 8 have firewalld.service that is just a front-end to what the kernel has (netfilter in 7, nftables in 8). The cockpit … is a GUI front-end to the firewalld?

Firewalld has zones. The default zone (public) has at least one service: ‘sshd’. That service allows access to port 22. The default for zone is to reject. One can add ports to zone, as you have done. Alternatively, one can define/modify services and add them to zone. A service might have auxiliary information, rather than just port(s).

Logically, you should have no use for the ‘sshd’ service in your firewalld zone, so you should remove it. How does one do that via cockpit? Frankly, I have no idea. Then again, I prefer nftables.service over firewalld.service even though its ruleset is way more manual and clearly less dynamic.

Thanks - helpful. I’m new to the ‘zones’ paradigm. I have (and periodically use) a variety of tools to manage the firewall - some CLI, some GUI, but all of them are pretty coarse grained. Seems like the only way to make really fine-grained rules is via CLI. I’m playing with firewall-cmd as we speak. The basics seem straightforward.

In cockpit, go to Networking → Firewall. Click Add-Services - Custom Ports. Add 1234 to the TCP line and give it a description. When finished, click “Add Ports”. It will reload firewalld for you.

Is it also possible to remove the “ssh” Service on that view? That is what OP wants to do.

@johnny_canuck A zone is group of machines, who are treated with same set of rules.

Lets say that you have neighbor’s A, B, C and D. Everybody else is E. You want to allow A and B in with SSH, B C, and D with HTTPS, and totally reject E.

You have therefore four zones:

  • SH allows SSH and HTTPS, members: B
  • S allows SSH, members: A
  • H allows HTTPS, members: C and D
  • X rejects

Each of the four zones rejects what they do not explicitly allow.

There is decoupling. In definition of zone you list rules. That is separate from who is “in that zone”.

Many thanks to all – most helpful, and instructive. My needs are simple – 3 total users (specified in hosts.allow) access the machine - 2 from outside our edge routers. They all connect via ssh to (alternate) port 1234 (say). Nothing more, nothing less. All other ports closed.

linux - Limit SSH access to specific clients by IP address - Unix & Linux Stack Exchange writes:

Note: this might not be an option on modern distributions, as support for tcpwrappers was removed from OpenSSH 6.7

Alma 8 does not have package tcp_wrappers – no package provides ‘/etc/hosts.allow’ and OpenSSH is based on version 8.0. Therefore, hosts.allow does not seem an option – firewall and sshd.conf are.

You have two zones. You could set the zone of interface to be block. That zone rejects all. Add the three IP addresses as sources for the zone that allows port 1234.

Indeed - so I just remembered for seeing your post.

But, there doesn’t seem to be any way (that I can find) to use ‘wildcards’ in firewalld. Suppose the ‘other users’ who need to connect to the machine are coming from systems where ip’s are allocated dynamically (DHCP). In hosts.allow/deny, this was trivial. I could simply use something like

sshd: xxx.yyy.zzz. : ALLOW

This would anyone in having an ip beginning with xxx.yyy.zzz.

So, options?

And, I suppose complicating things, I haven’t gennerally been able to use ip numbers (with or without wildcards). Most of the time, I simply have something like following, which works perfectly with tcp_wrappers.

sshd: : ALLOW


sshd : user12.friendlyisp. : ALLOW

[i.e., wildcard at either end…]

The xxx.yyy.zzz. means any address in range xxx.yyy.zzz.0 – xxx.yyy.zzz.255
So does CIDR notation xxx.yyy.zzz.0/24 and that you can use in the rules.

Names are a real issue, since the firewall should resolve those names into IP addresses.
However, the sshd config can have “Match blocks” and AlloUsers, where you can use wildcard hostnames. See man sshd_config

Nothing prevents you from filtering both at firewall (by address) and with sshd (by names).

OK - many thanks. I’m now understanding why so many people do not like (verging on loathing) firewalld and associated changes.

In my case, I’ll admit to being preemptively annoyed that it seems I’ll need to fiddle with both firewalld and my sshd config to accomplish something that took <10 seconds with a simple edit to hosts.allow/deny.

So, I just noticed tcp_wrappers is still available in EPEL. So, what happens if you ditch firewalld and simply revert back to tcp_wrappers? Not saying I’m going to do this, but I am curious…

Because sshd isn’t compiled with libwrap (or so ldd tells me).

If ldd shows that binary requires a lib, then binary can’t load without the lib. However, binaries can explicitly and optionally load libs that ldd does not show. Many programs have “plugins” by that method. I bet that sshd does not.

The shift away from tcp wrappers is unrelated to firewalld. Neither netfilter nor nftables supports names.

Firewalld is a front-end to present different logical concepts than what the kernel uses. Supposedly more “humane”. Veterans dislike the implementation. Myself … firewalld has lacked support for some operations that backend has.

Thanks for all the comments – basically, I find the transition from tcp_wrappers → firewalld to be a PITA. tcp_wrappers made is easy to control access by port, by ip, by number - any combination.

firewalld seems fine, and I’m getting a hdnale on zones, but doesn’t handle names (which I find kind of astounding - about 85% of the accesses to my server(s) come from ISP’s where the ip is allocated dynamically, with the ip blocks changing with some frequency. What doesn’t change? The name – so why won’t firewalld let me use names? Go figure…).

So, at the moment, I’ve cobbled together a hydrbrid where firewalld does some of the work, then tweaks to sshd_config (which does let me use names, in a fashion) does the rest.

I hope. :wink:

In theory one could make a service that resolves name to address frequently and updates the IP-address in the firewall rules. The nftables has sets (iptables had ipset). Updating a set should be quite efficient compared to updating the ruleset. No idea whether one can do that via firewalld.