You could build the described system using iptables, ipset and pam_exec.
The idea is following: There is a separate chain containing rules to allow incoming traffic to these higher ports. Iptables INPUT chain contains an ipset rule matching your logged in hosts, jumping to the separate chain.
On successful log in, a pam_exec runs a script (at PAM session open) adding the remote host's IP address to the ipset set, and similarly removes it when PAM session is closed.
Configuring IPTABLES and IPSET
Create a set for user's IP addresses. Since ipsets are not persistent, so you need to configure the set to be created on boot before iptables are restored.
ipset -N users hash:ip
Configure iptables. A new
INPUT-users chain which will contain the rules to allow traffic for logged in users.
iptables -N INPUT-users
If the source address is in
users set, jump to
iptables -A INPUT -m set --match-set users src -j INPUT-users
Add relevant rules to
INPUT-users chain. These rules will be used for traffic with source address matching your user's. For example to allow
iptables -A INPUT-users -p tcp --dport 16384
Create following scripts to be executed on pam session open/close. The IP address will be in
PAM_RHOST environmental variable set by
ipset --exist --add users "$PAM_RHOST"
ipset --del users "$PAM_RHOST"
Then configure pam to use them for ssh sessions. Append to
session optional pam_exec.so type=open_session /etc/security/pam_exec-session_open
session optional pam_exec.so type=close_session /etc/security/pam_exec-session_close
If your user has multiple ssh sessions open, closing any of them will remove the IP address from the ipset. To avoid this, you need to write some check for the session_close script to remove the IP address only if it is the last session remaining for the user.
Should your user connect behind NAT, after connecting anyone behind the same NAT will match the ipset rule (allowed access).